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, но лично, что кажется ненужным.