2010-07-21 64 views
5

Android文档说,在UI线程上调用AsyncTask postExecute()。我的印象是postExecute()被调用线程调用​​:我一直在使用自己的线程在后台服务中使用AsyncTask,而postExecute()在服务线程中调用,而不是在主线程中调用。
但是,我最近遇到了一个postExecute()问题,根本没有被调用,而抛出异常:“发送消息给死线程上的处理程序”。Android:AsyncTask可以在UI线程之外的另一个线程中返回吗?

它是怎么一回事:
- AsyncTask只能从主线程使用吗?
- 如果没有,应该调用哪个线程postExecute():始终是UI线程或​​调用线程?

谢谢

+0

文档*对我来说似乎有误导性,但我没有跑过你得到的异常是我的经验,当在UI线程外部使用'AsyncTask'时,onPostExecute'发生在调用线程中,而不一定是UI线程(如果UI需要被操作,则需要'Handler')。 – 2010-07-21 16:07:30

回答

14

在创建任务实例的线程上调用AsyncTask的pre和postExecute方法。你调用execute()的地方并不重要。您创建任务的线程必须是循环线程,并且在实践中应始终是主线程(或UI线程)。

+0

感谢您的具体答案! – 2010-07-21 16:38:26

+1

这是4.1+的情况吗?我已经在处理程序线程中启动了异步任务,但结果仍然在主线程中。 – Teodor 2013-04-08 13:09:50

+0

如果你在不同的线程上创建了一个监听器,那么怎么办?如果你调用它,它会在它创建的线程上触发吗? – JY2k 2015-01-11 09:44:05

2

看来你可以从别的地方开始的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次虽然...

+0

我猜是因为你已经调用了你的对象的execute来输入第一个doInBackground,所以onPostexecute被调用了4次。我不确定在doInBackground中嵌套任务的创建是个不错的主意...... – user244129 2010-07-21 17:07:36

相关问题