2013-02-26 123 views
5

मैं लगातार इस से निराश हूं और मुझे कोई अच्छा जवाब नहीं मिल रहा है, इसलिए उम्मीद है कि यहां कोई मार्गदर्शन प्रदान कर सकता है।टुकड़े, जब मैं "सक्रिय" हूं?

मेरे पास एक टुकड़ा है जो काफी व्यापक रूप से AsyncTask का उपयोग करता है। मैं लगातार बग्स से पीड़ित हूं जहां टुकड़ा getActivity() पर कॉल करता है, जो शून्य देता है। मुझे लगता है कि ये हो रहे हैं क्योंकि गतिविधि संलग्न होने से पहले, या अलग होने के बाद खंड में कुछ विधि बुलाई जाती है।

मेरे कोड में इसे संभालने का सही तरीका क्या है? मैं, इस मुहावरा हर जगह अटे पड़े है नहीं करना चाहती

Activity activity = getActivity(); 
if (activity != null) { // do something } 

Fragment के लिये दस्तावेज को देखते हुए, मैं हल करने के लिए कई संभावित हुक के साथ आने कर सकते हैं इस: isDetached(), onActivityCreated(), onAttach(), isResumed(), और शीघ्र। सही संयोजन क्या है?

संपादित करें:

कुछ लोगों जब रुका हुआ कार्य रद्द सुझाव दिया है, लेकिन यह संकेत मिलता है कि मानक मुहावरा,

new AsyncTask<...>.execute(); 

नहीं किया जा सकता। इसका तात्पर्य है कि प्रत्येक निष्पादित AsyncTask को पूरा करने या रद्द करने के लिए ट्रैक किया जाना चाहिए। मैंने बस कभी नहीं देखा है कि उदाहरण में Google या अन्य जगह से कोड। कुछ की तरह,

private final Set<AsyncTask<?>> tasks = new HashSet<>; 
... 
AsyncTask<?> t = new AsyncTask<...>() { 
    ... 
    public void onPostExecute(...) { 
    tasks.remove(this); 
    ... 
    } 
} 
tasks.add(t); 
t.execute(); 
... 
@Override 
public void onPause() { 
    for (AsyncTask<?> t: tasks) { 
    t.cancel(); 
    } 
    tasks.clear(); 
} 
+0

निश्चित रूप से कोई जवाब नहीं है, लेकिन ... आपकी बग वास्तुशिल्प है।मैं बिल्कुल नहीं जानता कि आप AsyncTasks के साथ क्या कर रहे हैं, लेकिन मैं कह सकता हूं कि अगर एक्टिविटी शून्य हो जाती है, जबकि उनमें से एक चल रहा है, तो आपको AsyncTask का उपयोग नहीं करना चाहिए। जो कुछ भी आप काम में कर रहे हैं, उसे सेवा में किया जाना चाहिए। एक गतिविधि/टुकड़ा जिसे खोजने के लिए राज्य की जरूरत है, वह सेवा प्राप्त करने के लिए कह सकती है। IntentService को देखें: यह उपयोग करना आसान है और AsyncTask से बहुत आसान है (ठीक है, अब प्रतीक्षा करें: यह वास्तव में AsyncTask से आसान है ** ** है, यह दिखाई देने से आसान नहीं है)। –

+0

@ जी। ब्लैकमेइक प्रतिक्रिया के लिए धन्यवाद। हमारे पास वास्तव में ऐप में दोनों पैटर्न हैं: 'IntentService' और' AsyncTask'। मैं 'AsyncTask' के कॉल अर्थशास्त्र पसंद करता हूं। पुन: गलत वास्तुकला- मुझे नहीं पता कि मैं सहमत हूं या नहीं। किसी भी समय आपको किसी संदर्भ की आवश्यकता होने पर आपको 'getActivity() 'कॉल करना होगा। इसलिए PostExecute() में एक स्ट्रिंग कहने की आवश्यकता है जिसका मतलब है कि मेरे पास गलत कमान है? –

+0

अच्छा .. हाँ, मुझे लगता है कि मैं जो कह रहा हूं वह काफी है। AsyncTask के साथ पूरा सौदा यह है कि इसमें एक जीवन चक्र है जो पूरी तरह से गतिविधियों से अलग है। आप किसी भी समय एटी के जीवन में किसी भी समय * किसी भी * गतिविधि संदर्भ पर भरोसा नहीं कर सकते हैं। क्या आपने एटी के कन्स्ट्रक्टर को एप्लीकेशन कॉन्टेक्स्ट पास करने पर विचार किया है? –

उत्तर

2

कोशिश या onStop तरीकों में अपने AsyncTasks रद्द करने के लिए। onPostExecute को Fragment अब सक्रिय नहीं होने पर रिटर्न null) से कॉल होने से onPostExecute को रोका जाएगा।

या आप Fragment को पर अपने Fragment पर कॉल करके संलग्न कर सकते हैं या नहीं।

+0

धन्यवाद। समस्या यह है कि मुझे प्रत्येक 'AsyncTask' को एक हैंडल रखने की आवश्यकता होगी जिसे मैं निष्पादित करता हूं। उदाहरण के लिए, उनमें से एक ढेर रखें, जब उन्हें 'onPostExecute()' कहा जाता है या जब मैं उन्हें रद्द करता हूं तो उन्हें पॉप करें। वहां कोई 'isAttached() 'विधि नहीं है, केवल' isDetached()' है, जो केवल तभी सही है जब टुकड़ा अलग किया गया है, न कि जब यह अभी तक संलग्न नहीं हुआ है (javadocs देखें)। –

+0

मैंने जवाब पोस्ट करने के बाद सीधे 'isAttached' विधि' isAddached' में बदल दिया है;) यह भी देखें http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity – nhaarman

+0

इसके अलावा, आम तौर पर मैं 'AsyncTask की प्रति' गतिविधि '/ 'Fragment' की संख्या को 3 से नीचे रखने की कोशिश करता हूं, ताकि यह करने योग्य हो। – nhaarman

0

जीवनशैली को समन्वयित करने के मामले में, मैं onActivityCreated को मानसिक बेंचमार्क के रूप में रखता हूं - यह उस बिंदु को चिह्नित करता है जिस पर अंतर्निहित गतिविधि ने अपना onCreate समाप्त कर दिया है। इससे पहले मुझे विश्वास नहीं है कि getActivity() से एक गतिविधि है।

यह गतिविधि नल ​​की आवाज़ें लौट रही है जैसे कि आप निष्क्रियता() बहुत जल्दी (यानी इसे बनाया जाने से पहले) या बहुत देर हो चुकी है (यानी जब यह खंड के साथ बातचीत करना बंद कर देता है)। onPause() में अपने कार्यों को रोकना निष्क्रियता को शून्य से वापस करने से रोक देगा क्योंकि एक बार खंड ने अंतर्निहित गतिविधि के साथ बातचीत करना बंद कर दिया है क्योंकि गतिविधि को रोक दिया गया था। मुझे लगता है कि onStop() के लिए इंतजार करना बहुत देर हो सकता है, अगर अंतर्निहित गतिविधि रोके जाने पर कार्य अभी भी चल रहा था, तो यह अभी भी शून्य हो सकता है।

1

मेरे अपने प्रश्न का उत्तर ...

मुझे कोई अच्छा समाधान नहीं मिला। संक्षेप में, या तो Loader का उपयोग करें, या जांचें कि getActivity() इसका उपयोग करने से पहले शून्य नहीं लौटाता है। मैंने Loader एस का उपयोग करने में देखा, लेकिन पैटर्न ऐप की संरचना और डेटा पुनर्प्राप्ति की प्रकृति के बारे में बहुत सारी धारणा करता है जो मेरे लिए काम नहीं करता है।