2013-03-27 6 views
1

Недавно я просмотрел SO, чтобы найти ответ to the same question here, но не было ответа, направленного на вопрос в отношении риска этого. Но в основном я хочу запустить еще один AsyncTask внутри метода doInBackground() другого AsyncTask. Это плохой подход и/или он оставляет какие-либо потенциальные побочные эффекты?Создание другой AsyncTask внутри doInBackground

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

ответ

4

Из API Docs:

• Экземпляр задачи должны быть созданы в потоке пользовательского интерфейса.

doInBackground() работает на фоне потока. Таким образом, вы не можете создавать и запускать другую асинтезу из doInBackground().

http://developer.android.com/reference/android/os/AsyncTask. Взгляните на тему под правилами .

Когда асинхронная задача выполняется, задача проходит через 4 этапа: (прямой от Doc)

1.onPreExecute(), вызывается в потоке пользовательского интерфейса, прежде чем задача будет выполнена. Этот шаг обычно используется для настройки задачи, например, показывая индикатор выполнения в пользовательском интерфейсе.

2. doInBackground (Params ...), вызывается на фоне потока сразу после onPreExecute() завершает выполнение. Этот шаг используется для выполнения фоновых вычислений, которые могут занять много времени. Параметры асинхронной задачи передаются на этот шаг. Результат вычисления должен быть возвращен этим шагом и будет возвращен на последний шаг. Этот шаг также может использовать publishProgress (Progress ...) для публикации одного или нескольких единиц прогресса. Эти значения публикуются в потоке пользовательского интерфейса на этапе onProgressUpdate (Progress ...).

3.onProgressUpdate (Прогресс ...), вызывается в потоке пользовательского интерфейса после вызова publishProgress (Прогресс ...). Время выполнения не определено. Этот метод используется для отображения любой формы прогресса в пользовательском интерфейсе, пока фоновое вычисление все еще выполняется. Например, его можно использовать для анимации индикатора выполнения или отображения журналов в текстовом поле.

4.onPostExecute (Result), вызывается в потоке пользовательского интерфейса после завершения вычисления фона. Результат вычисления фона передается на этот шаг в качестве параметра.

При первом вводе AsyncTasks выполнялись последовательно на одном фоновом потоке. Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. Начиная с HONEYCOMB, задачи выполняются в одном потоке, чтобы избежать ошибок обычного приложения, вызванных параллельным выполнением.

Если вы действительно хотите выполнить параллельное выполнение, вы можете вызвать executeOnExecutor (java.util.concurrent.Executor, Object []) с помощью THREAD_POOL_EXECUTOR.

Также вы можете использовать альтернативный RoboSpice. https://github.com/octo-online/robospice.

Можно сделать несколько запросов на пряность. Инициирует поток ui, когда задача завершена. Стоит взглянуть на robospice.

+0

Очень красивый и тщательный ответ вместе с несколькими альтернативами. Еще раз спасибо Raghunandan – JoeyL

+0

+1 за такой исчерпывающий ответ. Мне было интересно прочитать «Класс AsyncTask должен быть загружен в поток пользовательского интерфейса. Это делается автоматически с JELLY_BEAN.' (из документов) - знаете ли вы, что делается автоматически? –

+0

@ Дэвид Каунт проверить ссылку http://stackoverflow.com/questions/14978924/what-is-the-difference-between-loading-and-creating-asynctask-on-the-ui-thread. – Raghunandan

1

AsyncTask(), за исключением выпусков Honeycomb, выполняется серийно. Итак, нет, вы не можете выполнить другую AsyncTask() из doInBackground() - я думаю, я должен сказать, что я никогда не пробовал, но вряд ли вы достигнете желаемого эффекта.

Я спросил об исполнении AsyncTask() во время одного из часов Google Office. Прямо от их рта, когда его спросили: «Почему это изменилось с серийного на параллельное и обратно на серийное исполнение?»; «Потому что это сломало много вещей».

+1

Это не совсем так. Метод execute выполняет задачу на исполнителе по умолчанию, который, как вы говорите, является единственным исполнителем потока (последовательным), так как Honeycomb. Но вы можете выполнять задачи у своего собственного исполнителя с помощью [executeOnExecutor] (https://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor (java.util.concurrent.Executor,% 20Params ...)). Это хорошо работает для задач, которые можно безопасно выполнять параллельно. –

+0

@DavidCaunt 100% true. +1 Просто пытался сохранить это просто :) –

Смежные вопросы