Запуск асинхронной задачи в рабочем потоке - PullRequest
18 голосов
/ 19 марта 2012

У меня два вопроса:

  • Можем ли мы запустить / выполнить асинхронную задачу в рабочем потоке?
  • Если да, методы onPreExecute(), onProgressUpdate(Progress...) и onPostExecute(Result) вызывается в потоке пользовательского интерфейса?

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

Заранее спасибо!

Ответы [ 5 ]

15 голосов
/ 19 марта 2012

Из Android AsyncTask doc :

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

"execute (Params ...) должен быть вызван в потоке пользовательского интерфейса."

Так что я думаю, что ответ на ваш первый вопрос "нет". Что касается второго, эти методы все вызываются в потоке пользовательского интерфейса, но это немного спорно.

РЕДАКТИРОВАТЬ: Я не уверен, являются ли это абсолютными ограничениями или сильными предложениями, но в обоих случаях я бы порекомендовал им следовать.

6 голосов
/ 20 июня 2013

Только для записи: если вы запускаете AsyncTask вне UI-потока, onPreExecute не будет выполняться из UI-потока (но из потока вызывающего). Это приведет к исключению. Однако метод onPostExecute всегда будет выполняться в потоке пользовательского интерфейса. Надеюсь помочь кому-нибудь :) 1007 *

5 голосов
/ 01 октября 2012

Согласно Android doco, вы должны запустить AsyncTask из потока пользовательского интерфейса, но на самом деле это зависит от того, кто запускает эту строку в AsyncTask.class первым:

private static final InternalHandler sHandler = new InternalHandler();

Если у вас есть AsyncTask, который вызывается как из пользовательского интерфейса, так и из рабочего потока, вы можете обойти это ограничение, вызвав его сначала из потока пользовательского интерфейса. Если вы нажмете это первым из вашей рабочей нити, вы обречены. Я бы предпочел не полагаться на это, поскольку детали реализации могут измениться в любое время, но эти знания полезны, если вы, как и я, задаетесь вопросом «почему мой другой AsyncTask работает».

4 голосов
/ 04 февраля 2013

Из документа Android AsyncTask:

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

"execute (Params ...)в потоке пользовательского интерфейса. "

Итак, допустимо следующее.

new Thread(new Runnable() {
                @Override
                public void run() {
                    // do some work here

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            new MyAsyncTask(ctx).execute(); 
                        }
                    });
                }
            }).start();
0 голосов
/ 30 марта 2017

Проще говоря, мы можем запустить AsyncTask на рабочем месте.Вы можете просто выполнить AsyncTask в новом потоке, очень просто.Причина в исходном коде Android: [кликнуть здесь]

private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...