2011-02-10 10 views
16

मैंने एक AsyncTask कि मैं गतिविधि के onPause जीवन चक्र घटना में बंद कर दिया है, तो यह नहीं चलता है जब किसी एप्लिकेशन को छोड़ देता है, लेकिन यह इस के बावजूद चलती है। मैंने कुछ ट्रेसिंग जोड़ा और यह स्निपेट समस्या दिखाता है।एंड्रॉइड AsyncTask रद्द होने पर नहीं रुक जाएगा, क्यों?

Trace.d(TAG,"Task state: " + myTask.getStatus()); 
    myTask.cancel(true); 
    Trace.d(TAG,"Task state: " + myTask.getStatus()); 

आउटपुट:

Task state: RUNNING 
Task state: RUNNING 

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

अद्यतन: मैंने मुझे isCancelled() राज्य को दिखाने के लिए ट्रेसिंग भी जोड़ा और यह बदलता है। तो रद्द करने के लिए कॉल (सत्य) रद्द किए गए राज्य को गलत से सच में बदल रहा है, लेकिन स्पष्ट रूप से स्थिति पर कोई प्रभाव नहीं पड़ता है, या धागे को रोकता है।

+0

वहाँ अपने कार्य के अंदर पाश के लिए एक तरह से जाँच करने के लिए काम रोक दिया गया है या नहीं, और बस से बाहर निकलने के पाश है? –

+0

रद्द करने से वापसी मूल्य क्या है? क्या यह आपको बताता है कि इसे रद्द कर दिया? –

+0

@ जोएल हाँ, मैं ऐसा कर सकता हूं, लेकिन जैसा कि मैं अन्य स्थानों पर रद्द() विधि का उपयोग करता हूं, मैं समझना चाहता हूं कि यह ऐसा क्यों नहीं कर रहा है जो मैं इसे –

उत्तर

2

मैं गहरी खोदा और याद आया कि मेरे धागा एक नहीं बल्कि बुरी तरह से लिखी विधि इस युक्त बुला रहा था, एक के अंदर एक और धागा उत्पादन मैं रद्द करने की आवश्यकता तरीका यह धागा की जाँच करें:

public static void haveASleep(int milliseconds) 
{ 
    try 
    { 
     Thread.sleep(milliseconds); 
    } 
    catch (InterruptedException ie) 
    { 
     Trace.w(TAG,"Sleep interrupted"); 
    } 
} 

तो क्या हो रहा था गया था कि AsyncTask थ्रेड थोड़ी देर प्रतीक्षा करने के लिए इस विधि को कॉल करता है, और नींद के दौरान रद्द() विधि कॉल AsyncTask पर होती है, जो थ्रेड नींद में अपवाद का कारण बनती है। मेरे कोड unhelpfully पकड़ लिया और, कि अपवाद अवशोषित बजाय इसे प्रयोग AsyncTask को बंद करने की।

समाधान नींद पर अपवाद की तलाश करना था, और अगर इसे फेंक दिया जाता है, तो चुपचाप धागे से बाहर निकलने के लिए। ऐप अब अपेक्षित काम करता है, लेकिन ...

रद्द करने के तुरंत बाद स्थिति() विधि कॉल चल रहा है, लेकिन मुझे संदेह है क्योंकि इस पल में यह अभी भी चल रहा है, और ओएस ने अभी तक इसे बंद नहीं किया है नीचे। मुझे नहीं पता कि यह सच है, लेकिन यह मेरा सबसे अच्छा अनुमान है।

0

भले ही आप जानते हैं कि कैसे कार्य रद्द करना है, यह निर्धारित करना बहुत कठिन है कि आपका धागा किस स्थिति में रुक जाएगा। इसलिए मैं आपके थ्रेड को रोकने के लिए अपने स्वयं के सुरक्षित तरीके को लागू करने का सुझाव देता हूं, इसलिए आप सुनिश्चित होंगे कि आप किस स्थिति में रुक रहे हैं और आप सुनिश्चित हैं कि कोई मेमोरी लीक नहीं है, आदि। अधिक जानकारी से जावा में धागे को सुरक्षित में कैसे रोकें How to abort a thread in a fast and clean way in java?

+0

मैं AsyncTask का उपयोग कर रहा हूं जो जावा थ्रेड के चारों ओर एक एंड्रॉइड रैपर है सिद्धांत रूप से, कम से कम सिद्धांत में, थ्रेड को शुरू करना, प्रबंधित करना और रोकना आसान बनाता है। फिलहाल मुझे संदेह है कि मैं ब्रूट-बल को धागे को रोकने के लिए समाप्त हो जाऊंगा, लेकिन मैं समझना चाहता हूं कि रद्द() विधि ऐसा क्यों नहीं कर रही है जो ऐसा करने के लिए डिज़ाइन किया गया है। –

+0

AsyncTask सिर्फ एक एंड्रॉइड रैपर नहीं है। जावा थ्रेड पर इसका मुख्य लाभ यह है कि यूआई थ्रेड में निष्पादित विधियों का उपयोग करके आप इसे आसानी से गुई अपडेट कर सकते हैं। तो AsyncTask जावा थ्रेड के रूप में रोकने के साथ एक ही समस्या है। –

3

ध्यान रखें कि आपकी गतिविधि और आपके AsyncTask दो अलग-अलग धागे हैं। तो अगर आप AsyncTask को रद्द करते हैं, तो कार्य को रद्द करने के लिए कोड अभी तक नहीं चल सकता है! इसलिए आपको देख रहे हैं AsyncTask अभी भी अपने बग फिक्सिंग के बाद भी चल रहा है। मुझे नहीं लगता कि आपकी AsyncTask में doInBackground() तक स्थिति बदल जाएगी। यदि आप इस समस्या में चला रहे हैं

0

एक अन्य संभावित ख़तरा जाँच करने के लिए (इसलिए सुनिश्चित करें कि आप isCancelled() जाँच कर रहे हैं और जल्दी लौटने के लिए जब आप रद्द कर दिया गया है बनाते हैं!):

सुनिश्चित करें कि आप दो AsyncTasks शुरू नहीं कर रहे हैं ।

2
thread.cancel(true); 

केवल AsyncTask क्लास में एक चर सेट करता है। यदि आपको पहले से नहीं किया गया है तो आपको अपने पृष्ठभूमि कार्य में लूप लागू करना है। फिर प्रत्येक पुनरावृत्ति के लिए रद्द होने पर लूप को चेक और ब्रेक करें।

@Override 
protected Void doInBackground(Void... params) { 

    synchronized(this) { 

     for(int i = 0; i < 9000; i++) { 

      if(thread.isCancelled()) break; 

      // do stuff 

     } 

    } 

} 

फिर जब भी आपको इसे रोकने की आवश्यकता हो तो इसे रद्द करने के लिए सेट करें। फिर यह निम्नलिखित पुनरावृत्ति से पहले रुक जाएगा।

@Override 
public void onStop() { 

    super.onStop(); 

    thread.cancel(true); 

} 

@Override 
public void onDestroy() { 

    super.onDestroy(); 

    thread.cancel(true); 

} 
+0

"धागा" क्या है? –

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