2012-08-24 18 views
9

मैंने कुछ प्रश्नों को मेरे जैसा लगभग देखा है, लेकिन मुझे पूरा जवाब नहीं मिला जो मेरे सभी संदेहों को पूरा करता है .. तो यहां मैं हूं .. मान लीजिए कि आपके पास एक आंतरिक कक्षा के साथ एक गतिविधि है जो AsyncTask कक्षा को बढ़ाती है इस तरह:जब भी यह चल रहा है तब लॉन्चिंग गतिविधि बंद/नष्ट हो जाती है जब AsyncTask का क्या होता है?

public class MyActivity extends Activity {    
    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 
     protected Bitmap doInBackground(String... urls) { 
      return DownloadImage(urls[0]); 
     } 
     protected void onPostExecute(Bitmap result) { 
      ImageView img = (ImageView) findViewById(R.id.img); 
      img.setImageBitmap(result); 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     new DownloadImageTask().execute("http://mysite.com/image.png") 
    } 
} 

मान लीजिए कि गतिविधि को रोका या नष्ट कर दिया (शायद दो मामलों में अलग हैं), जबकि DownloadImageTask अभी भी पृष्ठभूमि में चल रहा है है .. तो, DownloadImageTask के तरीकों गतिविधि UI थ्रेड पर चलते हैं कि ट्रिगर किया जा सकता है और DownloadImageTask गतिविधि की विधियों तक पहुंचने का प्रयास कर सकता है (यह एक आंतरिक वर्ग है, इसलिए यह बाहरी वर्ग के विधियों और आवृत्ति चर का उपयोग कर सकता है) रोके या नष्ट गतिविधि के साथ, जैसेपर कॉल नीचे दिए गए उदाहरण में.. तब क्या होता है? क्या यह चुपचाप असफल हो जाता है? क्या यह कोई अपवाद उत्पन्न करता है? क्या उपयोगकर्ता को अधिसूचित किया जाएगा कि कुछ गलत हो गया है?

अगर हमें यह ध्यान रखना चाहिए कि लॉन्चिंग थ्रेड (इस मामले में गतिविधि) अभी भी जिंदा है, तो चल रहे यूआई विधियों को लागू किया जाता है, हम AsyncTask के भीतर से इसे कैसे पूरा कर सकते हैं?

यदि आप एक नकली प्रश्न के रूप में इस लगता है, लेकिन शायद इस सवाल का थोड़ा अधिक व्यक्त है और किसी को अधिक विस्तार

+1

जब आप इस कोड को चलाते हैं, तो क्या यह चुपचाप असफल हो जाता है, कोई अपवाद उत्पन्न करता है, या उपयोगकर्ता को सूचित करता है कि कुछ गलत हो गया है? – CommonsWare

+0

मैंने अभी तक ऐसा कोड नहीं चलाया है, मैं इसे अगले कुछ दिनों में करूँगा .. मैं अपने ऐप के कार्यान्वयन में जाने से पहले इसके बारे में सोच रहा था। जैसे ही मैं एक परीक्षण चला सकता हूं, मैं इस पोस्ट को अपडेट कर दूंगा।धन्यवाद @ कॉमन्सवेयर –

+1

मेरा मुद्दा यह है कि व्यवहार अनियंत्रित है, विशेष रूप से इस तथ्य को देखते हुए कि हम गतिविधि में कुछ और नहीं देख रहे हैं। 'findViewById()' 'r.id.img' के लिए' null' वापस कर सकता है, या ऐसा नहीं हो सकता है। और एंड्रॉइड ओएस रिलीज, डिवाइस निर्माता बदलाव, और रोम मोड के आधार पर यह व्यवहार डिवाइस से डिवाइस में भिन्न रूप से भिन्न हो सकता है। – CommonsWare

उत्तर

3

साथ जवाब कर सकते हैं इस कार्य पर विचार करें (जहां R.id.test एक को संदर्भित करता है मैं माफी चाहता हूँ मेरी गतिविधि के लेआउट में मान्य दृश्य):

public class LongTaskTest extends AsyncTask<Void, Void, Void>{ 
    private WeakReference<Activity> mActivity; 
    public LongTaskTest(Activity a){ 
     mActivity = new WeakReference<Activity>(a); 
    } 
    @Override protected Void doInBackground(Void... params) { 
     LogUtil.d("LongTaskTest.doInBackground()"); 
     SystemClock.sleep(5*60*1000); 
     LogUtil.d("mActivity.get()==null " + (mActivity.get()==null)); 
     LogUtil.d("mActivity.get().findViewById(R.id.frame)==null " + (mActivity.get().findViewById(R.id.test)==null)); 
     return null; 
    } 
} 

अगर मैं ऐसा तरह एक गतिविधि के onCreate से इस कार्य को चलाएँ: कोई फर्क नहीं पड़ता

public class Main extends Activity { 
    @Override 
    public void onCreate(Bundle state) { 
     super.onCreate(state); 
     setContentView(R.layout.testlayout); 
     new LongTaskTest(this).execute(); 
     finish(); 
    } 
} 

कितनी देर तक मैं पृष्ठभूमि सो धागा, मेरी लॉग हमेशा पता चलता है:

LongTaskTest.doInBackground() 
mActivity.get()==null false 
mActivity.get().findViewById(R.id.frame)==null false 

कौन सा कहने के लिए गतिविधि और इसके दृश्यों को जीवित रहने के लिए (भले ही मैं मैन्युअल रूप से डी डी एम एस के माध्यम से जेंटलमैन कैडेट जारी) दिखाई देते हैं। अगर मैं अधिक समय था मैं एक स्मृति डम्प को देखो चाहते हैं, लेकिन अन्यथा मैं वास्तव में क्यों यह मामला है पता नहीं है ... लेकिन अपने प्रश्नों के जवाब में ऐसा लगता है कि:

  • यह करता है चुपचाप असफल? नहीं
  • क्या यह कोई अपवाद उत्पन्न करता है? नहीं
  • क्या उपयोगकर्ता को सूचित किया जाएगा कि कुछ गलत हो गया है? नहीं
+0

गतिविधि अभी भी वहां हो सकती है क्योंकि आपकी आंतरिक कक्षा का इसका संदर्भ है, लेकिन इसमें दृश्यों और आवृत्ति चर के बारे में कैसे? – user412759

+0

यही कारण है कि मैंने गतिविधि के लिए वीक रेफरेंस का उपयोग किया ... यह सुनिश्चित करने के लिए कि मेरी आंतरिक कक्षा कारण नहीं थी क्योंकि गतिविधि को जीवित रखा गया था। विचारों और आवृत्ति चर के रूप में, मेरी आंतरिक कक्षा में वीक रेफरेंस को गतिविधि के अलावा कोई नहीं है। जब तक आप कुछ और मतलब नहीं है? वीक रेफरेंस पर अधिक: http://developer.android.com/reference/java/lang/ref/WeakReference.html – newbyca

+3

@newbyca यदि वास्तव में 'लॉन्गटास्कटेस्ट' एक आंतरिक वर्ग है, तो इसका गतिविधि गतिविधि का एक निहित संदर्भ है आप भूल रहे हैं - इसे एक स्थिर नेस्टेड क्लास बनाएं: http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class – MattJenko

2

आपकी गतिविधि नष्ट हो जाने पर भी डिनबैकग्राउंड() चल रहा है (i, ई आपका मुख्य धागा नष्ट हो जाता है) क्योंकि doInBackground() विधि कार्यकर्ता/पृष्ठभूमि धागे पर चलती है। ऑनपोस्टएक्सक्यूट() विधि को चलाने में 'समस्या' होगी क्योंकि यह मुख्य/यूआई थ्रेड पर चलता है और आप असंबद्ध डेटा में चलने का अनुभव कर सकते हैं लेकिन उपयोगकर्ता को कोई अपवाद नहीं दिखाई देगा। इस प्रकार, जब आपकी गतिविधि नष्ट हो जाती है तो अपने AsyncTask को रद्द करना हमेशा बेहतर होता है क्योंकि गतिविधि अब मौजूद नहीं होने पर AsyncTask चलाने का कोई कारण नहीं है। यदि आपका घटक/गतिविधि नष्ट हो जाती है तब भी आप नेटवर्क से कुछ डाउनलोड करना चाहते हैं, तो एंड्रॉइड सेवा का उपयोग करें। धन्यवाद।

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

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