Android: как передать параметры в onPreExecute () AsyncTask?

116

Я использую AsyncTaskдля операций загрузки, которые я реализовал как внутренний класс.

В onPreExecute()I показать диалог загрузки , который я затем скрыть снова onPostExecute(). Но для некоторых операций загрузки я заранее знаю, что они завершатся очень быстро, поэтому я не хочу отображать диалог загрузки.

Я хотел указать это логическим параметром, которому я мог бы передать, onPreExecute()но, по-видимому, по какой-то причине onPreExecute()не принимает никаких параметров.

Очевидным обходным путем, вероятно, было бы создание поля-члена в моей AsyncTask или во внешнем классе, которое мне пришлось бы устанавливать перед каждой операцией загрузки, но это не кажется очень элегантным. Есть лучший способ сделать это?

Стивен Мелиопулос
источник

Ответы:

230

Вы можете переопределить конструктор. Что-то вроде:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    public MyAsyncTask(boolean showLoading) {
        super();
        // do stuff
    }

    // doInBackground() et al.
}

Затем при вызове задачи сделайте что-нибудь вроде:

new MyAsyncTask(true).execute(maybe_other_params);

Изменить: это более полезно, чем создание переменных-членов, поскольку упрощает вызов задачи. Сравните приведенный выше код с:

MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
Феликс
источник
3
Именно это я и сделал сейчас. Мне все еще нужна переменная-член, но в AsyncTask, а не во внешнем классе, если вы это имеете в виду. Вот что я сделал: частный класс MyAsyncTask расширяет AsyncTask <Void, Void, Void> {private boolean showLoading; общедоступный MyAsyncTask (логическое showLoading) {супер (); this.showLoading = showLoading; // делаем что-то} protected void onPreExecute () {if (showLoading) {// ...}} // doInBackground () и др. }
Стивен Мелиопулос
1
Да, в этом и была идея :)
Felix
1
На самом деле вам не нужен super () в конструкторе AsynkTask.
ostergaard
62

1) Для меня самый простой способ передачи параметров в асинхронную задачу выглядит следующим образом

// To call the async task do it like this
Boolean[] myTaskParams = { true, true, true };
myAsyncTask = new myAsyncTask ().execute(myTaskParams);

Объявите и используйте задачу async, как здесь

private class myAsyncTask extends AsyncTask<Boolean, Void, Void> {

    @Override
    protected Void doInBackground(Boolean...pParams) 
    {
        Boolean param1, param2, param3;

        //

          param1=pParams[0];    
          param2=pParams[1];
          param3=pParams[2];    
      ....
}                           

2) Передача методов в асинхронную задачу Чтобы избежать многократного кодирования инфраструктуры асинхронной задачи (поток, обработчик сообщений, ...), вы можете рассмотреть возможность передачи методов, которые должны выполняться в вашей асинхронной задаче, в качестве параметра. Следующий пример описывает этот подход. Кроме того, вам может потребоваться создать подкласс асинхронной задачи для передачи параметров инициализации в конструктор.

 /* Generic Async Task    */
interface MyGenericMethod {
    int execute(String param);
}

protected class testtask extends AsyncTask<MyGenericMethod, Void, Void>
{
    public String mParam;                           // member variable to parameterize the function
    @Override
    protected Void doInBackground(MyGenericMethod... params) {
        //  do something here
        params[0].execute("Myparameter");
        return null;
    }       
}

// to start the asynctask do something like that
public void startAsyncTask()
{
    // 
    AsyncTask<MyGenericMethod, Void, Void>  mytest = new testtask().execute(new MyGenericMethod() {
        public int execute(String param) {
            //body
            return 1;
        }
    });     
}
Карл
источник
11

почему, как и какие параметры передаются в Asynctask <>, см. подробности здесь . Думаю, это лучшее объяснение.

Документация Google для Android гласит:

Асинхронная задача определяется 3 универсальными типами, называемыми Params, Progress и Result, и 4 шагами, называемыми onPreExecute, doInBackground, onProgressUpdate и onPostExecute.

Общие типы AsyncTask:

Асинхронная задача использует следующие три типа:

Params, тип параметров, отправляемых задаче при выполнении. Прогресс, тип единиц прогресса, публикуемых во время фоновых вычислений. Результат, тип результата фоновых вычислений. Не все типы всегда используются асинхронной задачей. Чтобы пометить тип как неиспользуемый, просто используйте тип Void:

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Вы можете дополнительно сослаться на: http://developer.android.com/reference/android/os/AsyncTask.html

Или вы можете выяснить, какова роль AsyncTask, обратившись к блогу Санкар-Ганеша

Что ж. Структура типичного класса AsyncTask выглядит так:

private class MyTask extends AsyncTask<X, Y, Z>

    protected void onPreExecute(){ 

    } 

Этот метод выполняется перед запуском нового потока. Здесь нет значений ввода / вывода, поэтому просто инициализируйте переменные или все, что, по вашему мнению, вам нужно сделать.

protected Z doInBackground(X...x){

}

Самый важный метод в классе AsyncTask. Вы должны разместить здесь все, что хотите делать в фоновом режиме, в другом потоке, отличном от основного. Здесь у нас есть в качестве входного значения массив объектов из типа «X» (вы видите в заголовке? У нас есть «... extends AsyncTask» Это ТИПЫ входных параметров) и возвращает объект из типа «Z».

protected void onProgressUpdate (Y y) {

} Этот метод вызывается с использованием метода publishProgress (y), и он обычно используется, когда вы хотите показать какой-либо прогресс или информацию на главном экране, например, индикатор выполнения, показывающий ход операции, которую вы выполняете в фоновом режиме.

protected void onPostExecute (Z z) {

} Этот метод вызывается после выполнения фоновой операции. В качестве входного параметра вы получите выходной параметр метода doInBackground.

А как насчет типов X, Y и Z?

Как вы можете сделать вывод из приведенной выше структуры:

X  The type of the input variables value you want to set to the background process. This can be an array of objects.

 Y  The type of the objects you are going to enter in the onProgressUpdate method.

 Z  The type of the result from the operations you have done in the background process.

Как мы называем эту задачу из внешнего класса? Просто со следующими двумя строками:

MyTask myTask = new MyTask();

myTask.execute(x);

Где x - входной параметр типа X.

Когда наша задача будет запущена, мы сможем узнать ее статус «извне». Использование метода «getStatus ()».

myTask.getStatus (); и мы можем получить следующий статус:

ВЫПОЛНЯЕТСЯ - указывает, что задача выполняется.

ОЖИДАНИЕ - указывает, что задача еще не выполнена.

ЗАВЕРШЕНО - указывает, что onPostExecute (Z) завершился.

Подсказки по использованию AsyncTask

Не вызывайте методы onPreExecute, doInBackground и onPostExecute вручную. Система делает это автоматически.

Вы не можете вызвать AsyncTask внутри другой AsyncTask или Thread. Вызов метода execute должен выполняться в потоке пользовательского интерфейса.

Метод onPostExecute выполняется в потоке пользовательского интерфейса (здесь вы можете вызвать другую AsyncTask!).

Входными параметрами задачи может быть массив объектов, таким образом вы можете поместить любые объекты и типы, которые захотите.

Навид Джамали
источник
4

Вы можете передать параметр в конструкторе задачи или при вызове execute:

AsyncTask<Object, Void, MyTaskResult>

Первый параметр (Object) передается в doInBackground. Третий параметр (MyTaskResult) возвращается doInBackground. Вы можете изменить их на нужный вам тип. Три точки означают, что ноль или более объектов (или их массив) могут быть переданы в качестве аргумента (ов).

public class MyActivity extends AppCompatActivity {

    TextView textView1;
    TextView textView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);    
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);

        String input1 = "test";
        boolean input2 = true;
        int input3 = 100;
        long input4 = 100000000;

        new MyTask(input3, input4).execute(input1, input2);
    }

    private class MyTaskResult {
        String text1;
        String text2;
    }

    private class MyTask extends AsyncTask<Object, Void, MyTaskResult> {
        private String val1;
        private boolean val2;
        private int val3;
        private long val4;


        public MyTask(int in3, long in4) {
            this.val3 = in3;
            this.val4 = in4;

            // Do something ...
        }

        protected void onPreExecute() {
            // Do something ...
        }

        @Override
        protected MyTaskResult doInBackground(Object... params) {
            MyTaskResult res = new MyTaskResult();
            val1 = (String) params[0];
            val2 = (boolean) params[1];

            //Do some lengthy operation    
            res.text1 = RunProc1(val1);
            res.text2 = RunProc2(val2);

            return res;
        }

        @Override
        protected void onPostExecute(MyTaskResult res) {
            textView1.setText(res.text1);
            textView2.setText(res.text2);

        }
    }

}
живи любя
источник