Android AsyncTask - Порядок исполнения

Я столкнулся с проблемой относительно порядка извлечения AsyncTasks.

Мой вопрос:

Предполагая, что у меня есть 2 реализации AsyncTask: MyAsyncTask1 и MyAsyncTask2

Они вызываются следующим образом:

new MyAsyncTask1 ().execute ();
new MyAsyncTask2 ().execute ();

Гарантируется ли, что MyAsyncTask1 выполняется до MyAsyncTask2? Одно точно, они не выполняются параллельно, поскольку используется исполнитель по умолчанию, который SERIAL_EXECUTOR. Проблема заключается в порядке выполнения: который будет выполнен первым?

Если порядок выполнения не определен, как я могу принудительно выполнить порядок выполнения для AsyncTasks?

Мне нужно, чтобы MyAsyncTask1 выполнялся до MyAsyncTask2, что не всегда так, но я вызываю execute для MyAsyncTask1 до MyAsyncTask2.

То, что у меня действительно есть, - это настраиваемая деятельность:

public abstract class CustomActivity extends Activity {

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        super.onCreate ( savedInstanceState );
        new MyAsyncTask2 ().execute ();
    }
}

И еще одно действие, которое наследуется от пользовательской активности:

public class MainActivity extends CustomActivity {

    @Override
    protected void onCreate ( Bundle savedInstanceState ) {
        new MyAsyncTask1 ().execute ();
        super.onCreate ( savedInstanceState );
    }
}

Итак, если я использую MainActivity, MyAsyncTask1 должен быть выполнен до MyAsyncTask2, по крайней мере, это то, что мне нужно.

Ответ 1

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

В вашем случае, чтобы сохранить абстрагирование реализации и не нужно фактически называть AsyncTask2 в onPostExecute AsyncTask1 (способ, предложенный Anup и Sanket, который также хорош, если вы хотите их смешать), сделайте вызов AsyncTask1 super.executeAsyncTask2(), где executeAsyncTask2() - это метод в вашей CustomActivity, который запускает вторую AsyncTask

Ответ 2

Чтобы "цепочки" любого числа AsyncTasks, то, что я делаю, это то, что мои AsyncTasks получают пользовательский обратный вызов в качестве параметра. Вам просто нужно определить его так:

public interface AsyncCallback(){
    public void onAsyncTaskFinished();
}

Конструктор реализации AsyncTask должен иметь AsyncCallback как параметр, например:

private AsyncCallback callback;

public AsyncTaskImplementation(AsyncCallback callback){
    //Do whatever you're doing here
    this.callback = callback;
}

Конечно, если у них больше параметров, не удаляйте их.

Затем, незадолго до конца onPostExecute, введем это:

if (callback != null) callback.onAsyncTaskFinished();

Итак, если вы передадите обратный вызов, AsyncTask выполнит ваш обратный вызов в основном потоке. Если вы не хотите выполнять обратный вызов, просто перейдите null

Итак, чтобы назвать цепочку AsyncTask, вы просто пишете это:

new AsyncTask1(new AsyncCallback(){

    public void onAsyncTaskFinished(){
         new AsyncTask2(null).execute();
    }

}).execute();

Я надеюсь, что это поможет вам; -)

Ответ 3

Вызов второй задачи Async в конце первой задачи Aysnc (т.е. в конце метода onPostExecute() вашей первой задачи async)

//first async task onPostExecute method

onPostExecute()
{
//do your stuff and call second async task

new MyAsyncTask2 ().execute ();

}

Это гарантирует выполнение второй задачи после первого в простой и элегантной форме.

Ответ 4

Вызов второй задачи в onPostExecute задачи 1 а

@Override
protected void onPostExecute(String string){//String or whatever u passed
    new MyAsyncTask2 ().execute ();
}

Ответ 5

AsyncTask выполняется в фоновом режиме, поэтому в вашем случае первый код запустит task1 и сразу же запустит task2.. поэтому вызовите

new MyAsyncTask2 ().execute ();

это для постэксплуатации Task1

Ответ 6

Не делайте вещи сложными и старайтесь держать свой дизайн простым и чистым. Гонка между вашими и AsyncTasks зависит от объема обработки, которую они выполняют в своих переопределенных методах. Логически, если вы хотите, чтобы ваш AsyncTask1 завершился до AsyncTask2, просто добавьте кодовые блоки второй Async в первую.

Или запустите второй Async из onPostExecute вашего первого Async, но лично, что кажется ненужным.