यह सर्वविदित है कि एंड्रॉयड किसी भी क्षण में हत्या किए जाने का खतरा मंडरा रहा हमारे आवेदन घटकों (क्रियाएँ, सेवा) देता है। यदि आप एक ही समय में कोड साफ रखने और चिंताओं की जुदाई को संबोधित कर, एक मजबूत, गैर टपकाया समाधान प्रदान करने के लिए चाहते हैं तो यह बातें वास्तव में जटिल बना देता है।अच्छा डिजाइन: कार्यकर्ता धागे और गतिविधि पुनरारंभ
समस्या:
एक गतिविधि (एक Runnable
, AsyncTask
या जो भी अन्य तंत्र के रूप में) एक समय लेने वाला कार्य शुरू होता है। एक प्रगति संवाद प्रदर्शित किया जाना चाहिए। कार्य कई कनेक्शन खुल जाएगा, लेकिन यह एक प्रगति बार अद्यतन करने का एक साधन होना चाहिए, और यह पूरा करने के लिए एक विकल्प संवाद आधे रास्ते प्रदर्शित करने के लिए आवश्यकता हो सकती है। यह संवाद बंद करने और एक त्रुटि होने पर टोस्ट दिखाने में सक्षम होना चाहिए, या जब यह पूरा हो जाता है।
जब एक गतिविधि मार दिया जाता है और बाद में एक नया उदाहरण निर्मित है, मैं दो विकल्प के बारे में सोच सकते हैं: चल रहा है काम को मारने के लिए
कोशिश के रूप में अच्छी तरह से है, और किसी अन्य कार्य उदाहरण अंडे जब एक नया विकल्प गतिविधि उदाहरण बनाया गया है। यह एक लंबा चल रहा कार्य के लिए एक विकल्प के रूप में यह अस्वीकार्य है से देखने के एक उपयोगकर्ता बिंदु कार्य प्रारंभ करने और प्रगति बार सूचक किसी स्पष्ट कारण के साथ वापस 0% से 80% तक से जा रहा करने के लिए नहीं है। हालांकि यह दृष्टिकोण Shelves example by Romain Guy में किया गया है। जाहिर है यह आधिकारिक डेवलपर गाइड में अनुशंसित दृष्टिकोण है।
रखें कार्य चल रहा है: तो हम पर एक गतिविधि
onResume
पर की सदस्यता (और संभवतः शुरू) अद्यतन के लिए काम, और सदस्यता समाप्ति (और संभवतः रोक) यह हो सकता था।
दूसरे विकल्प के बाद इसका मतलब है कि गतिविधि को अस्थायी रूप से नष्ट करने के मामले में हमें एकत्रित होने के कार्य को रोकना चाहिए। उदाहरण के लिए, हम इसे एक कस्टम एप्लिकेशन क्लास के भीतर घोषित कर सकते हैं, या यहां तक कि इसे बाकी एप्लिकेशन के लिए एक सेवा के रूप में भी पेश कर सकते हैं (एक सिंगलटन? एंड्रॉइड सर्विस का उपयोग कर?) मैं इस का कोई प्रशंसक नहीं हूं, हालांकि, कार्य है केवल गतिविधि द्वारा उपयोग किया जाता है, इसलिए इसे अन्य वर्गों में उपलब्ध कराने के लिए यह समझ में नहीं आता है। दूसरी तरफ एंड्रॉइड सर्विसेज को जीवन चक्र से निपटना होगा।
विकल्प # 2 में यह भी शामिल है कि पुराने गतिविधि को लीक नहीं किया गया है। यदि कोई गतिविधि मौजूद नहीं है तो हमें जीयूआई अपडेट करने की कोशिश नहीं करनी चाहिए। पूरा विचार थ्रेड-सुरक्षित होना चाहिए। अंत में कार्य को स्मृति में नहीं रहना चाहिए जब हमें यकीन है कि इसकी आवश्यकता नहीं है। लेकिन साथ ही, यदि प्रारंभिक गतिविधि नष्ट हो जाती है, तो कार्य चल रहा रहता है, और एक नई विकल्प गतिविधि बढ़ जाती है, कार्य को तुरंत जीयूआई अपडेट करने के लिए आसपास होना चाहिए और कार्य वर्तमान स्थिति प्रदर्शित करना होगा (या परिणामस्वरूप पूरा होने पर)।
तथ्य यह है कि कोई गतिविधि दिखाए जाने पर कार्य चल रहा है, इससे निपटने के लिए एक और समस्या है, क्योंकि हमें किसी बिंदु पर उपयोगकर्ता इंटरैक्शन (पसंद संवाद) को सिंक्रनाइज़ करने की आवश्यकता हो सकती है। तक पहुंचने पर गतिविधि को तत्काल कार्य को रोकने की क्षमता होने पर इसे हल किया जा सकता है, लेकिन कार्य को रोकने के लिए कुछ समय लग सकता है या ऐसा करने में असमर्थ भी हो सकता है।
मुझे पता है कि पहले से ही इसी तरह के प्रश्न पूछे गए हैं, लेकिन मैं विशेष रूप से समस्या को हल करने के बारे में नहीं पूछ रहा हूं, लेकिन ढीले युग्मन को प्राप्त करने और कार्य से गतिविधि को अलग करने के लिए किस डिजाइन की सिफारिश की जाएगी मुमकिन।
कम में:
- यह शायद पहले एक चालाक डिजाइन के साथ आ गया Android विकास और किसी में एक आवर्ती समस्या है। क्या कोई डिज़ाइन पैटर्न है, या एक अच्छी तरह से परीक्षण लाइब्रेरी है जो इसे सरल बनाती है?
- यदि आप # 2 को लागू करना चाहते हैं, तो आप किस वर्ग (कार्यशील, सेवा, आदि) के लिए चुनते हैं और यह गतिविधि के साथ कैसे संवाद करेगा?
पीएस "अभिविन्यास | कीबोर्डहेड" हैक एक्सडी के आधार पर समाधान पोस्ट करने से बचें। इसके अलावा, किसी भी मदद की सराहना की जाएगी।
अद्यतन:
मेरे पहले ही प्रयास में थोड़ा गंदा मिल गया है। ऐप एक ब्लूटूथ प्रिंटिंग यूटिलिटी है, जिसमें बीटी स्टेटस का पता लगाना शामिल है (और उपयोगकर्ता को अक्षम होने पर इसे सक्षम करने के लिए कहा जाता है), युग्मित उपकरणों को पुनर्प्राप्त करना (और उपयोगकर्ता को एक से अधिक होने पर एक चुनने के लिए कहना), फिर डेटा भेजना और अंत में परिणाम के बारे में उपयोगकर्ता को सूचित करें। चूंकि यह कार्य 80% आईओ कोड था, 20% जीयूआई से संबंधित संचालन, मुझे कार्य की शुरुआत और अंत में जीयूआई कोड को समूहबद्ध करना था, फिर इसे कार्य से वापस गतिविधि में ले जाना था। मेरे पास IntentService
है जो भारी भारोत्तोलन करता है, फिर BroadcastReceiver
के माध्यम से गतिविधि पर वापस रिपोर्ट करता है। इससे ज्यादातर समस्याएं हल होती हैं लेकिन ऐसे डिज़ाइन के साथ कुछ समस्याएं हैं। सबसे पहले, उन सभी स्थिर तारों को इनपुट और आउटपुट से फ़ील्ड को रखने और पुनर्प्राप्त करने के लिए कुंजी के रूप में उपयोग किया जाता है, जो अर्थपूर्ण युग्मन शुरू कर रहे हैं। मैं गतिविधि < -> सेवा संचार में टाइप-सुरक्षा पसंद करूंगा। और मुझे अभी तक यह हल करना है कि इरादे में सेवा के लिए जटिल कस्टम ऑब्जेक्ट्स को कैसे पास किया जाए, अब तक मैं पार्ससेलबल्स और आदिम पैरामीटर के साथ फंस गया हूं। अंत में, गतिविधि और सेवा दोनों एक ही एपीआई (ब्लूटूथ) का उपयोग कर रहे हैं, मैं एक ही कक्षा में बीटी-संबंधित कोड अल करना पसंद करता। मुझे लगता है कि मैं इस डिजाइन को फेंक दूंगा, और धागे के आधार पर एक कस्टम प्रिंटिंग कतार के साथ पुनः प्रयास करूंगा, भले ही इससे मारे गए गतिविधियों से कड़ी मेहनत हो जाएगी।
AsyncTask गतिविधि को फिर से बनाया गया है, जबकि रोका गया है। प्रगति/परिणाम के लिए कार्य का उपयोग किया गया संदेश तब तक वितरित नहीं किया जाता है जब गतिविधि नष्ट हो जाती है (फिर भी रोकें/फिर से शुरू होने के बाद भी हो सकता है)। गतिविधि उदाहरणों के बीच AsyncTask के आसपास पास करने के लिए nonconfiguration-instance चीज़ का उपयोग करना काफी अच्छा काम करना चाहिए। – zapl