2010-07-21 14 views
5

एंड्रॉइड प्रलेखन का कहना है कि यूआई थ्रेड पर AsyncTask postExecute() कहा जाता है। मैं इस धारणा के तहत था कि postExecute() को थ्रेड से बुलाया गया था जहां execute() कहा गया था: मैं अपने स्वयं के धागे के साथ पृष्ठभूमि सेवा में एक AsyncTask का उपयोग कर रहा हूं, और पोस्टएक्सक्यूट() को सर्विस थ्रेड में मुख्य थ्रेड नहीं कहा गया था।
हालांकि, मुझे हाल ही में postExecute() के साथ कोई समस्या नहीं थी, जबकि एक अपवाद फेंक दिया गया था: "एक मृत धागे पर हैंडलर को एक संदेश भेजना"।एंड्रॉइड: क्या यूआई थ्रेड की तुलना में AsyncTask किसी अन्य थ्रेड में वापस आ सकता है?

यह वास्तव में कैसा है:
- क्या AsyncTask केवल मुख्य धागे से उपयोग किया जाएगा?
- यदि नहीं, तो किस धागे में postExecute() कहा जाता है: हमेशा यूआई थ्रेड, या execute() थ्रेड कॉलिंग?

धन्यवाद

+0

प्रलेखन * प्रकट होता है * मुझे भी भ्रामक करता है, जबकि मैं पूरे भाग में नहीं चलाता अपवाद जो आपको मिल रहा है यह मेरा अनुभव रहा है कि यूआई थ्रेड 'ऑनपोस्टएक्सक्यूट' के बाहर 'AsyncTask' का उपयोग करते समय कॉलिंग थ्रेड से होता है और जरूरी नहीं कि यूआई थ्रेड (तब यूआईएलर की आवश्यकता होती है यदि यूआई को छेड़छाड़ की जरूरत है)। –

उत्तर

14

AsyncTask के पूर्व और पोस्ट निष्पादन विधियों को उस थ्रेड पर बुलाया जाता है जिस पर कार्य उदाहरण बनाया गया था। जहां आप execute() कहते हैं, इससे कोई फर्क नहीं पड़ता। जिस धागे पर आप कार्य बनाते हैं वह एक लूपर थ्रेड होना चाहिए और अभ्यास में हमेशा मुख्य धागा (या यूआई थ्रेड) होना चाहिए

+0

ठोस उत्तर के लिए धन्यवाद! –

+1

क्या यह अभी भी 4.1+ में मामला है? मैंने हैंडलर थ्रेड के भीतर एसिंक कार्य शुरू कर दिया है लेकिन परिणाम अभी भी मुख्य धागे पर है। – Teodor

+0

क्या आपके पास एक अलग थ्रेड पर एक श्रोता बनाया गया है? यदि आप कॉल करते हैं तो क्या यह थ्रेड पर भी ट्रिगर होगा? – JY2k

2

ऐसा लगता है कि आप मुख्य थ्रेड से कहीं और से AsyncTask शुरू कर सकते हैं लेकिन वास्तव में postExecute मुख्य थ्रेड पर निष्पादित किया जाता है। यहाँ मेरी परीक्षा है, मुझे बताओ अगर यह आप के लिए तार्किक लगता है:

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 बार किया जाता है:

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

यहाँ कार्यों के बाद स्टैकट्रेस है हालांकि ...

+0

मुझे लगता है क्योंकि आपने अपने ऑब्जेक्ट पर पहले doInBackground में प्रवेश करने के लिए निष्पादित किया है, इसलिए पोस्टस्टेक्ट्यूट को 4 बार कहा जाता है। मुझे यकीन नहीं है कि doInBackground में कार्य के निर्माण को घोंसला करना एक अच्छा विचार है हालांकि ... – user244129

संबंधित मुद्दे