2010-07-21 14 views
5

Android belgeleri, UI iş parçacığında AsyncTask postExecute()'un çağrıldığını söylüyor. execute()'un çağrıldığı Konudan postExecute() çağrıldığı izlenim altındaydım: Kendi iş parçacığıyla bir Arka Plan Hizmetinde bir AsyncTask kullanıyorum ve ana iş parçacığı değil, hizmet iş parçacığında postExecute() çağrıldı.
Bununla birlikte, son zamanlarda postExecute() ile hiç çağrılmayan bir sorunla karşılaştım, bir istisna atıldı: "bir iş parçacığına bir iş parçacığına ileti gönderme".Android: AsyncTask, kullanıcı arabiriminden başka bir konuya geri dönebilir mi?

Tam olarak nasıl:
- AsyncTask SADECE ana başlıktan kullanılmalıdır?
- eğer değilse postExecute() hangi iş parçacığının çağrılması gerekiyor: her zaman UI iş parçacığı veya execute() çağrı iş parçacığı?

Eğer

+0

belgeleri * Görünen * de bana yanıltıcı, ben rastlamadım varken istisnası mutlaka UI iş parçacığı değil çağıran iplikle meydana gelir ve onPostExecute' UI iş parçacığı 'dışında bir' AsyncTask' kullanırken (UI manipüle edilmesi gerekiyorsa o zaman bir 'Handler' gerektiren) benim deneyim olmuştur alıyorsanız. –

cevap

14

AsyncTask'ın pre ve postExecute yöntemleri, görev örneğinin oluşturulduğu iş parçacığında çağrılır. Execute() işlevini nerede aradığınız önemli değil. Eğer görev oluşturmak hangi iplik bir ilmek ipliği olmalı ve pratikte her zaman ana iş parçacığı olmalıdır (veya UI iş parçacığı.)

+0

Somut cevap için teşekkürler! –

+1

Bu hala 4.1 + 'da durum mu? İşleyici iş parçacığı içinde eşzamansız bir görev başlattım ancak sonuç hala ana iş parçacığı. – Teodor

+0

Farklı bir iş parçacığı üzerinde oluşturulmuş bir dinleyiciniz varsa ne olacak? eğer bunu çağırırsanız, oluşturduğu iş parçacığı da tetiklenir mi? – JY2k

2

ana Konu daha başka yerden AsyncTask başlayabilirsiniz görünüyor ederim ama postExecute gerçekten ana iş parçacığı üzerinde yürütülür. İşte benim sınavım, size mantıklı görünüyor olmadığını söyleyebilir:

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 

sonrası yürütmek neden bilmiyorum 4 kez yapılır: Burada

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()); 
} 
} 

görevler sonra StackTrace olduğunu bununla birlikte ...

+0

Sanırım ilk doInBackground'a girmek için nesnenizde execute çağrınız çünkü onPostexecute buna 4 kez denir. DoInBackground görevinin yaratılışının iç içe geçmesinin iyi bir fikir olduğuna emin değilim ... – user244129

İlgili konular