Android: AsyncTask может возвращать в другой поток, чем поток пользовательского интерфейса? - PullRequest
5 голосов
/ 21 июля 2010

Документация Android гласит, что AsyncTask postExecute() вызывается в потоке пользовательского интерфейса. У меня сложилось впечатление, что postExecute() был вызван из потока, где был вызван execute(): я использовал AsyncTask в фоновом сервисе с собственным потоком, а postExecute () вызывался в потоке службы, а не в основном нить.
Однако недавно у меня возникла проблема с тем, что postExecute () вообще не вызывался, в то время как было сгенерировано исключение: «отправка сообщения обработчику в мертвой ветке».

Как это точно:
- следует ли использовать AsyncTask ТОЛЬКО из основного потока?
- если нет, то в каком потоке предполагается вызывать postExecute(): всегда поток UI или execute() вызывающий поток?

Спасибо

Ответы [ 2 ]

14 голосов
/ 21 июля 2010

Методы pre и postExecute AsyncTask вызываются в потоке, в котором был создан экземпляр задачи.Где вы вызываете execute (), не имеет значения.Поток, в котором вы создаете задачу, должен быть зацикленным и на практике всегда должен быть основным (или потоком пользовательского интерфейса).

2 голосов
/ 21 июля 2010

Кажется, что вы можете запустить AsyncTask не из основного потока, но postExecute действительно выполняется в основном потоке Вот мой тест, скажите, если он кажется вам логичным:

public class AsyncLoader extends AsyncTask<Context, String, Boolean> {
private ConnectivityManager cm;
private ArrayList<Contact> nameList;
private Context ctx;
private static int i = 0;

@Override
protected Boolean doInBackground(Context... params) {
    ctx = params[0];
    cm = (ConnectivityManager) params[0].getSystemService(Activity.CONNECTIVITY_SERVICE);
    if (i < 3) {
        i++;
        new AsyncLoader().execute(ctx);
        System.out.println("Thread name (from doInBackground) : " + Thread.currentThread().getName());
        System.out.println("compteur async " + i);
    }
    if (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isAvailable()) {
        nameList = (ArrayList<Contact>) ContactLoaderXml.loadContactsData(); //this is a loading from the web + sax parser
        return true;
    } else {
        return false;
    }
}
@Override
protected void onPostExecute(Boolean result) {
    super.onPostExecute(result);
    System.out.println("Thread name (from postexecute) : " +  Thread.currentThread().getName());
}
}

Вот трассировка стека после задач:

I/System.out(  641): Thread name (from doInBackground) : AsyncTask #1  
I/System.out(  641): compteur async 1  
I/System.out(  641): Thread name (from doInBackground) : AsyncTask #2  
I/System.out(  641): compteur async 2  
I/System.out(  641): Thread name (from doInBackground) : AsyncTask #3  
I/System.out(  641): compteur async 3  
I/System.out(  641): Thread name (from postexecute) : main  
I/System.out(  641): Thread name (from postexecute) : main  
I/System.out(  641): Thread name (from postexecute) : main  
I/System.out(  641): Thread name (from postexecute) : main 

Я не знаю, почему пост выполняется 4 раза ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...