Android: Як я можу передати параметри на AsPreExecute () AsyncTask?


116

Я використовую операції AsyncTaskдля завантаження, які я реалізував як внутрішній клас.

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

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

Очевидним вирішенням, ймовірно, було б створення поля-члена в моєму AsyncTask або у зовнішньому класі, який я повинен був би встановити перед кожною операцією завантаження, але це не здається дуже елегантним. Чи є кращий спосіб зробити це?

Відповіді:


231

Ви можете перекрити конструктор. Щось на зразок:

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 (булева шоуLoading) {super (); this.showLoading = showLoading; // робити речі} захищені невідомі onPreExecute () {if (showLoading) {// ...}} // doInBackground () та ін. }
Стівен Меліопулос

1
Так, це була ідея в основному :)
Фелікс

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) Передача методів до завдання async. Щоб уникнути кодування інфраструктури async-Task (потік, messagenhandler, ...) кілька разів, ви можете розглянути можливість передачі методів, які повинні бути виконані у вашій задачі async, як параметр. Наступний приклад окреслює цей підхід. Крім того, у вас може виникнути необхідність підкласировать завдання async для передачі параметрів ініціалізації в конструктор.

 /* 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

чому, як і які параметри передаються до Асинтактаска <>, детально дивіться тут . Я думаю, що це найкраще пояснення.

Документація Google для Android говорить:

Асинхронна задача визначається трьома загальними типами, що називаються Парамами, Прогресом та Результатом, та 4 кроками, які називаються onPreExecute, doInBackground, onProgressUpdate та onPostExecute.

Загальні типи AsyncTask:

Три типи, що використовуються асинхронною задачею, є наступними:

Парами, тип параметрів, що надсилаються завданням після виконання. Прогрес, тип одиниць прогресу, опублікованих під час обчислення фоном. Результат, тип результату обчислення фону. Не всі типи завжди використовуються асинхронним завданням. Щоб позначити тип як невикористаний, просто використовуйте тип 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" (Ви бачите в заголовку? У нас є "... extens AsyncTask" (це типи вхідних параметрів)) і повертає об'єкт від типу "Z".

захищена void onProgressUpdate (Y y) {

} Цей метод називається за допомогою методу публікуватиProgress (y), і він зазвичай використовується, коли ви хочете показати будь-який прогрес або інформацію на головному екрані, як-от панель прогресу, що показує хід операції, яку ви виконуєте у фоновому режимі.

захищена пустота 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. Виклик виконавця методу повинен здійснюватися в потоці інтерфейсу користувача.

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

Вхідними параметрами завдання може бути масив Object, таким чином ви можете розміщувати будь-які об'єкти та типи, які ви хочете.


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);

        }
    }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.