Запустить задачу Async в рабочем потоке
У меня есть два вопроса:
- Можно ли запустить/выполнить задачу Async в рабочем потоке?
- Если да, методы
onPreExecute()
, onProgressUpdate(Progress...)
и onPostExecute(Result)
вызывают в потоке пользовательского интерфейса?
Я хочу знать, что, поскольку у меня есть TCP-соединение, работающее в рабочем потоке, и когда пакет получен, я хочу начать новый поток, чтобы выполнить синтаксический анализ этого пакета, и после этого обновить некоторые структуры данных в потоке пользовательского интерфейса.
Спасибо заранее!
Ответы
Ответ 1
Из Android AsyncTask doc:
"Экземпляр задачи должен быть создан в потоке пользовательского интерфейса." и
"execute (Params...) должен быть вызван в потоке пользовательского интерфейса."
Итак, я думаю, что ответ на ваш первый вопрос - "нет". Что касается второго, эти методы все вызывается в потоке пользовательского интерфейса, но это немного спорно.
EDIT: Я не уверен, что это абсолютные ограничения или сильные предложения, но в обоих случаях я бы рекомендовал их следовать.
Ответ 2
В соответствии с Android doco вы должны запустить AsyncTask из потока пользовательского интерфейса, но на самом деле это зависит от того, кто сначала запускает эту строку в AsyncTask.class:
private static final InternalHandler sHandler = new InternalHandler();
Если у вас есть AsyncTask, вызываемый как из пользовательского интерфейса, так и из рабочего потока, вы можете обойти это ограничение, вызвав его сначала из потока пользовательского интерфейса. Если вы ударите его сначала из рабочего потока, вы обречены.
Я бы предпочел не полагаться на это, поскольку детали реализации могут меняться в любое время, но это знание полезно, если вы, как и я, задавались вопросом, "почему работает моя другая AsyncTask".
Ответ 3
Из документа 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();
Ответ 4
Только для записи: если вы запустите AsyncTask вне пользовательского интерфейса, onPreExecute не будет выполняться из UI-Thread (но из потока вызывающего), Это приведет к исключению. Однако метод onPostExecute всегда будет выполняться в UI-Thread. Надеюсь помочь кому-то:)
Ответ 5
В простой форме мы можем запустить AsyncTask у рабочего. Вы можете просто запустить AsyncTask в новом потоке, очень просто.
Причина в исходном коде Android:
[clike here]
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
}