किसी गतिविधि में बनाए गए पंजीकृत / अनरजिस्टर्ड ब्रॉडकास्टर रजिस्टर कब करें?


79

मुझे एक गतिविधि के onCreate कार्यक्रम में एक कस्टम प्रसारण रिसीवर बनाने की आवश्यकता है और जाहिर है मुझे गतिविधि के onDestroy घटना में प्रसारण रिसीवर को अनरजिस्टर्ड करने की आवश्यकता है

स्पष्टता के लिए यह मेरे द्वारा उपयोग किए जाने वाले कोड का एक स्निपेट है

public class AnActivity extends Activity {
    private ResponseReceiver receiver;

    public class ResponseReceiver extends BroadcastReceiver {
           public static final String ACTION_RESP =
              "mypackagename.intent.action.MESSAGE_PROCESSED";

           @Override
            public void onReceive(Context context, Intent intent) {
// TODO Start a dialogue if message indicates successfully posted to server
            }
    }   

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new ResponseReceiver();
        registerReceiver(receiver, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

मैंने पढ़ा है कि गतिविधि के लिए onPause / onResume और onStart / onStop इवेंट को भी पंजीकृत होना चाहिए और प्रसारण रिसीवर को अनरिजर्व करना चाहिए।

मैं वास्तव में यह समझना चाहता हूं कि इसके लिए सबसे अच्छा अभ्यास क्या माना जाता है और क्यों।


ऐसा इसलिए है क्योंकि जब onDestroy()कॉल किया जाता है तो ईवेंट रिसीवर द्वारा नहीं सुने जाएंगे।
de_billa_

जवाबों:


91

आप पंजीकरण करना होगा और अपने रिसीवर अपंजीकृत onStart()और onStop()

किसी गतिविधि को पंजीकृत करने का एकमात्र कारण BroadcastReceiverवर्तमान गतिविधि पर किसी तरह से ईवेंट का उपयोग करना, किसी ईवेंट के उपयोगकर्ता को सूचित करना है। यदि onStop()बुलाया गया है, तो Activityअब अग्रभूमि में नहीं है, और इसलिए उपयोगकर्ता को अपडेट नहीं कर सकते।

यदि आप पृष्ठभूमि में प्रसारण कार्यक्रम प्राप्त करना चाहते हैं, तो आपको एक सेवा का उपयोग करने पर विचार करना चाहिए जैसा कि यहां बताया गया है

जैसा कि कॉन्स्टेंटिन कहता है, onDestroy()को बुलाए जाने की गारंटी नहीं है, और आप लंबे समय तक प्रसारण प्राप्त करना जारी रख सकते हैं, जब यह Activityअब खुला नहीं है।


3
क्या आप यह सुझाव दे रहे हैं कि मैं onCreate के INSTEAD में या साथ ही रजिस्टर करता हूं? OnResume हमेशा कहा जाता है जब एक गतिविधि बनाई जाती है?
प्रात:

9
आपको रजिस्टर करना चाहिए onResume हाँ, onResume () को हमेशा प्रदर्शित होने वाली गतिविधि पर बुलाया जाता है (यह आपकी गतिविधि दिखाई देने से पहले बुलाया जाने वाली अंतिम विधि है ( डेवलपर ।android.com/reference/android/app/Activity.html ) यदि आप केवल रजिस्टर करें। () और अपंजीकृत ऑनपॉज (), फिर अगली बार गतिविधि को अग्रभूमि में लाया जाता है, ऑनक्रिएट () को फिर से कॉल नहीं किया जाएगा और फिर वह रिसीवर को फिर से पंजीकृत नहीं करेगा। और हां मेरा मतलब है कि INSTEAD, इसे ऑनक्रिएट न करें। ()।
स्नोइक्रेट्स

1
@SnowyTracks: क्या आप इस पर टिप्पणी कर सकते हैं कि यह onRume / onPtop के बजाय onResume / onPause में BroadcastReceiver पंजीकरण कॉल करने के लिए बेहतर क्यों है? बाध्य सेवाओं के लिए डेवलपर गाइड की तलाश में, मुझे यह मिला । इस खंड के अंत में, किसी को onResume / onPause (प्रदर्शन कारणों से) के बजाय onStart / onStop में सर्विस बाइंडिंग / अनबाइंडिंग करने की सलाह दी जाती है। मुझे आश्चर्य है कि क्या यह ब्रॉडकास्टर्स पर भी लागू होता है? अग्रिम में धन्यवाद।
जनुस वर्मकरन २०

1
@jvmk सहमत, एंड्रॉइड डॉक्टर onStart और onStop में ऐसा करने के लिए कहता है, मुझे लगता है कि 99% मामलों में, इससे बहुत कम फर्क पड़ता है, व्यवहार में केवल अंतर होता है संवाद गतिविधियों या या तो आंशिक अग्रभूमि गतिविधियों का उपयोग किया जाता है। लेकिन मैं अपने उत्तर को अपडेट करने के लिए एंड्रॉइड
डॉक्स

1
मैं देख रहा हूँ कि आपने कल दूसरे पैराग्राफ को संपादित किया है ... एक अधिक सुसंगत उत्तर पर प्रयास करने के लिए धन्यवाद। लेकिन यह अभी भी यह स्पष्ट नहीं करता है कि किसी को onResume / onPause के संयोजन में या इसके बजाय onStart / onStop का उपयोग क्यों करना चाहिए , जो OP का प्रश्न था। इसके बजाय, दूसरे पैराग्राफ की व्याख्या onResume / onPause पर समान रूप से सही है क्योंकि यह onStart / onStop का है: एक बार ऑनपॉज़ को कॉल करने के बाद, गतिविधि अग्रभूमि में नहीं रह जाती है। इसलिए हम आपकी अनुशंसा के बिना "क्यों" छोड़ गए हैं।
लार्स

19

जैसा कि onDestroy()आप को बुलाया जाएगा की गारंटी नहीं है आप onPause()डेरेगिस्टर का उपयोग करेंगे । अपने प्रसारण रिसीवर के जीवनचक्र पर विचार करें: क्या आपको सक्रिय होने की आवश्यकता है, केवल तभी जब आपकी गतिविधि अग्रभूमि में हो? तब उपयोग onResume()/onPause()


क्या होगा अगर हमें अभी भी गतिविधि में सामग्री को अपडेट करने की आवश्यकता है, भले ही गतिविधि पृष्ठभूमि में हो, क्योंकि उपयोगकर्ता एप्लिकेशन को फिर से शुरू कर सकता है और उस मामले में अद्यतन डेटा दिखाया जाना चाहिए?
उस्मान राणा

9

Android दस्तावेज़ रजिस्टर करने के लिए / अपंजीकृत प्रसारण रिसीवर एक ही स्थान निर्धारित नहीं है, लेकिन यह उल्लेख है दोनों onStart()/ onStop()और onResume()/ onPause()संभावनाओं के रूप में।

यह निर्णय लेने में सबसे बड़ा कारक यह है कि आपके रिसीवर को अपना काम करने में सक्षम होने की आवश्यकता कब है? यह निर्धारित करेगा कि इसे कब पंजीकृत करना और अपंजीकृत करना है।

  • क्या रिसीवर को केवल प्रसारण के बारे में कुछ करने की ज़रूरत है जब गतिविधि ध्यान में हो? यदि हां, तो आप में यह अपंजीकृत रजिस्टर कर सकते हैं / onPause()/ onReceive()। (आप एक लंबे जीवनकाल का उपयोग भी कर सकते हैं जैसे onStart()/ onStop(), लेकिन फिर आपको रिसीवर के दौरान जांच करनी चाहिए कि onReceive()क्या गतिविधि ध्यान में है)

  • क्या दिखाई देने पर रिसीवर को कुछ करने की आवश्यकता होती है, भले ही उसमें फोकस न हो (जैसे कि जब कोई डायलॉग दिखाया जा रहा हो)? यदि ऐसा है, तो उपयोग करें onStart()/ onStop()(या एक लंबा जीवनकाल, लेकिन फिर से, रिसीवर onReceive()को जांचना चाहिए कि क्या गतिविधि दिखाई दे रही है)।

  • क्या गतिविधि दिखाई न देने पर भी रिसीवर को प्रसारण के बारे में जानना आवश्यक है? उदाहरण के लिए, यह है कि जब गतिविधि को याद है कि कुछ हुआ है की जरूरत है, ऐसा नहीं करता है हो जाता है दिखाई, यह मामलों के परिणामस्वरूप राज्य को प्रतिबिंबित कर सकते हैं? फिर आपको पंजीकरण / अपंजीकृत करने के लिए onCreate()/ उपयोग करने की आवश्यकता है onDestroy()। (ध्यान दें कि इस तरह की कार्यक्षमता को लागू करने के अन्य तरीके हैं।)

यदि आप में पंजीकरण onStart()करते हैं, तो उन्हें भी पंजीकृत न करें onResume(), क्योंकि यह निरर्थक होगा: onResume()कभी भी onStart()पहले बुलाया नहीं जाता है ।

यह भी ध्यान रखें कि ऑनपोज़ () जितना संभव हो उतना हल्का रखना सबसे अच्छा है :

ऑनपॉज () निष्पादन बहुत संक्षिप्त है, और जरूरी नहीं कि बचाए गए कार्यों को करने के लिए पर्याप्त समय दे। इस कारण से, आपको एप्लिकेशन या उपयोगकर्ता डेटा को बचाने, नेटवर्क कॉल करने या डेटाबेस लेनदेन को निष्पादित करने के लिए ऑनपॉज़ () का उपयोग नहीं करना चाहिए; हो सकता है कि यह कार्य विधि पूर्ण होने से पहले पूरा न हो। इसके बजाय, आपको onStop () के दौरान भारी-लोड शटडाउन संचालन करना चाहिए।

यह सच है कि onDestroy()है कहा जा करने की गारंटी नहीं है, तो सिस्टम को स्मृति को बचाने के लिए अपनी प्रक्रिया को मारता है। हालाँकि, यदि प्रक्रिया को मार दिया जाता है, तो प्रक्रिया को वैसे भी प्रसारण प्राप्त नहीं होगा। उस मामले में, क्या प्रसारण रिसीवरों को अपंजीकृत करना वास्तव में आवश्यक है?


मेरे प्रश्न के उत्तर के लिए आपका धन्यवाद, लेकिन आपका उत्तर भ्रमित करने वाला है और कड़ाई से सटीक नहीं है। आप कहते हैं कि If you register in onStart(), don't also register them in onPause(), because that would be redundant: onPause() is never called without onStart() being called first.यह केवल अतार्किक और भ्रामक है, खासकर जब स्वीकृत उत्तर पूरी तरह से सटीक हो।
jamesc

@jamesc: उफ़, मेरा मतलब onResume था बजाय ऑनपॉज़ के। आप सही कह रहे हैं, यह थोड़ा भ्रमित करने वाला है। अभी तय किया है। स्वीकृत उत्तर के लिए, मैंने इस पर टिप्पणी की है। मेरा मानना ​​है कि यह उत्तर महत्वपूर्ण और प्रासंगिक जानकारी जोड़ता है जो स्वीकार नहीं करता है।
लार्स

5

एंड्रॉइड आपके एप्लिकेशन को ओमटिंग onStop()विधि से मार सकता है । उस स्थिति को हल करने का सबसे अच्छा तरीका विधि BroadcastReceiverमें पंजीकृत है onResume()और में अपंजीकृत है onPause()


1
मैं भी यही कर रहा हूं। के साथ किया था समस्याओं onStop()के रूप में अच्छी
Vygintas बी

0

आपको रजिस्टर करना चाहिए और अपने प्रसारण को onResume () और onPause () विधियों में अपंजीकृत करना चाहिए।

यदि आप onStart () में रजिस्टर करते हैं और इसे onStop () में अपंजीकृत करते हैं। उस समय आपको निम्नलिखित समस्या मिलेगी।

यदि आपकी डिवाइस स्क्रीन लॉक है तो उस समय onStop () कहा जाता है और यदि आप उस समय को अनलॉक करते हैं तो onStart () को कभी नहीं बुलाया जाता है। यही कारण है कि आपके पास रजिस्टर है और इसे अनरिजर्व () और ऑनपॉज () विधियों में अपंजीकृत करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.