2010-07-21 63 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

相關問題