Подтвердить что ты не робот

Запустить задачу Async в рабочем потоке

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

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

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

Спасибо заранее!

4b9b3361

Ответ 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());
    }
}