2011-08-26 13 views
9

1) मुझे कम नहीं लगता है कि एंड्रॉइड के नमूने लगभग AsyncTasks को निजी आंतरिक कक्षाओं के रूप में क्यों उपयोग करते हैं। मुझे पता है कि इसे आंतरिक कक्षा बनाना सुविधाजनक है लेकिन यह हमारी कक्षा फ़ाइल को पढ़ने के लिए लंबा और कठिन बनाता है। अलमारियों शेल्फ के नमूने के आवेदन में 845 लाइनें भी हैं। क्या आपको नहीं लगता कि यह एक खराब डिजाइन या खराब निर्माण है?यदि AsyncTask एक आंतरिक वर्ग नहीं है ... - कुछ प्रश्न

2) यदि मैं अपना स्कैनस्टोरेज टास्क बाहरी वर्ग बना देता हूं, तो मुझे इसे पास करने के लिए क्या करना होगा? पूरी गतिविधि या केवल इस्तेमाल विजेट?

उदाहरण: यदि मुझे स्कैनस्टोरेज टास्क में एक वेबव्यू, एक बटन और प्रोग्रेसबार का उपयोग करना चाहिए। करने के लिए

ScanStorageTask task = new ScanStorageTask(webView, button, progressBar); 

उत्तर

14

बाहरी रूप से ऐसा करने में कुछ भी गलत नहीं है, और यह वास्तव में एक बेहतर डिज़ाइन हो सकता है। आसपास के यूआई तत्वों को पास करना तंग युग्मन की तरह है जो आपको परेशानी में डाल सकता है जब आपके पास वास्तव में एक बड़ा कोड बेस है।

इसे बाहरी रूप से क्यों न करें और "श्रोता" पैटर्न का उपयोग करें जो यूआई नियंत्रण नियोजित करता है?अपने ScanStorageTask को अपनी कक्षा बनाएं, ऑनकंपलेट लिस्टनर इंटरफ़ेस को ऑन-अप विधि के साथ बनाएं, और इसे अपने स्कैनस्टोरेज टास्क इंस्टेंस में पास करें (एक सेटऑन कॉम्प्लेटी लिस्टनर विधि या उस प्रभाव से कुछ का खुलासा करें)। फिर, onPostExecute सिर्फ यह कर सकते हैं:

if(onCompleteListener != null) 
    onCompleteListener.onComplete(data); 

इस तरह, आप डेटा के आधार पर अपनी गतिविधि के अंदर अपने यूआई अद्यतन परिभाषित करते हैं। यह चिंताओं का बेहतर अलगाव है और प्रति वर्ग कोड की आपकी लाइनों को नीचे रखेगा, जैसा कि ऐसा लगता है कि आप क्या पसंद करेंगे। यदि आपके पास पहले से ऐसा नहीं है, तो उस वर्ग को बनाएं जो आपको उस डेटा का प्रतिनिधित्व करता है जिसमें आपको पास करने और बाहर निकलने की आवश्यकता होती है, और यह कार्य निष्पादन विधि के लिए एक पैरा के रूप में आप कार्य में पास करते हैं औरपोस्टएक्सक्यूट पर पूर्ण होने पर क्या होता है।

+0

आप सही हैं, यूआई तत्वों को पार करना बहुत परेशानी है। मैं वास्तव में गतिविधि से AsyncTasks decouple करने के लिए कुछ करना चाहता हूँ। श्रोता पैटर्न विचार के बारे में धन्यवाद। – Emerald214

+0

मेरी इच्छा है कि आपके पास कोड नमूना – CodyBugstein

+1

@Imray मुझे बताए कि यह मदद करता है। मैंने इस वर्ग को बनाया है, और अब मैं अपने सभी async कार्यों के लिए विस्तार करता हूं: https://github.com/aguynamedrich/beacon-utils/blob/master/Library/src/us/beacondigital/utils/tasks/Task.java – Rich

6

इनर कक्षाएं आप पूरे यूआई संरचना (रों) गुजर बिना एक बाहरी ActivityonPreExecute() अंदर, onPostExecute() और onProgressUpdate() के यूआई हेरफेर करने की अनुमति:

ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it. 

या इस: मैं इस का उपयोग AsyncTask। आप इसके लिए सक्रियण कार्यों का उपयोग करने में सक्षम हैं।

यूआई में हेरफेर करने के बाद यह उपयोगी है क्योंकि AsyncTask का मुख्य उद्देश्य नहीं है। यह गैर-यूआई पृष्ठभूमि काम कर रहा है। और इसके लिए, आपको आमतौर पर जो करना है वह यह काम करने के लिए कुछ तर्क है (उदाहरण के लिए फ़ाइल डाउनलोड करने के लिए यूआरएल की आपूर्ति करना)।

जब आप अपना असिनकटास्क बाहरी घोषित करते हैं, तो आप मूल रूप से onPreExecute() के अंदर अपने यूआई संसाधनों तक नहीं पहुंच सकते हैं (इस पर कोई तर्क पारित नहीं किया जाता है), और अन्य दो यूआई कार्यों के अंदर बहुत कठिन है।

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

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

(the class documentation से)

+0

पिछली रात थ्रेड httpRequest के साथ इस अनुकरणीय मुद्दे में भाग लें। जब अनुरोध हैंडलर को एक संदेश देता है, तो मैं अपनी गतिविधि सामग्री को रीफ्रेश करना चाहता हूं, लेकिन यह बाहरी कक्षा में नहीं हो सकता है। मैं कहूंगा कि एंड्रॉइड और अन्य मोबाइल सिस्टम में कभी-कभी यह गतिविधि के अंदर सबसे ज्यादा कुछ करने के बाद से अधिक बनाता है। आप पठनीयता खो देते हैं लेकिन अधिकतर कुछ चक्रों को बचाने की संभावना – NSjonas

+0

देखें/गतिविधि डेटा आमतौर पर इसके कन्स्ट्रक्टर में AsyncTask को पास किया जाता है। –

2
  1. व्यक्तिगत तौर पर मैं belive कि यदि आप केवल एक बिंदु पर वर्ग का उपयोग करें, तो यह सबसे पठनीय भी इसे परिभाषित करने की है - इसलिए शीघ्र भीतरी वर्ग।

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

4

मुझे आवेदन में एक ही समस्या थी। मैं Socket का उपयोग कर एक पीसी के साथ एक संवाद स्थापित करना चाहता था और मैं चाहता था कि मेरे कोड को कई क्रियाकलापों/टुकड़ों से पुन: प्रयोज्य किया जाए।

पहली जगह मैं एक आंतरिक वर्ग का उपयोग नहीं करने की कोशिश की लेकिन यह बहुत सुविधाजनक है आप यूआई अपडेट करना पड़ता है जब तो मैं वैकल्पिक समाधान:
मैं आरोप में एक बाहरी AsyncTask वर्ग जो के साथ संवाद करने के लिए बनाया पीसी और मैंने onPostExecute() विधि के केवल ओवरराइड के साथ अपने प्रत्येक सक्रियण/टुकड़ों में आंतरिक कक्षाएं बनाई हैं। इस तरह से मैं अपना कोड पुन: उपयोग कर सकता हूं और यूआई अपडेट कर सकता हूं।

यदि आप केवल कार्य का परिणाम प्राप्त करना चाहते हैं और यदि आपके आवेदन के लिए उत्तरदायित्व आवश्यक नहीं है, तो आप AsyncTask कक्षा के get() विधि का उपयोग कर सकते हैं।

+0

'get() 'का उपयोग करना बिल्कुल ठीक है यदि आपको केवल अपनी पृष्ठभूमि प्रक्रिया के परिणाम की आवश्यकता होती है। एक जादू की तरह काम करता है! – kaolick

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