2012-06-26 11 views
43

अन्य धागे से जीयूआई अद्यतन करने के लिए, वहाँ मूल रूप से दो मुख्य दृष्टिकोण हैं:अद्यतन कर रहा है जीयूआई: Runnables बनाम संदेश

Activity.runOnUiThread(Runnable) 
View.post(Runnable) 
View.postDelayed(Runnable, long) 
Handler.post(Runnable) 
  • : इन तरीकों में से किसी के साथ

    1. उपयोग java.lang.Runnable

      उपयोग android.os.Message:

      Handler.sendMessage(Message)/Handler.handleMessage(Message) 
      

    आप AsyncTask का भी उपयोग कर सकते हैं, लेकिन मेरा प्रश्न एक बहुत ही सरल घटक को अद्यतन करने के उपयोग के मामले पर अधिक केंद्रित है। चलो देखते हैं कि यह कैसे उपयोग किया जा दोनों दृष्टिकोण:

    1. का उपयोग Runnables:

      TextViev tv = ...; 
      final String data = "hello"; 
      Runnable r = new Runnable() { 
      
          @Override 
          public void run(){ 
           tv.setText(data); 
          } 
      
      }; 
      //Now call Activity.runOnUiThread(r) or handler.post(r), ... 
      
    2. का उपयोग करते हुए संदेश:

      Message m = handler.obtainMessage(UPDATE_TEXT_VIEW, "hello"); 
      handler.sendMessage(m); 
      
      //Now on handler implementation: 
          @Override 
          public void handleMessage(Message msg) { 
           if(msg.what == UPDATE_TEXT_VIEW){ 
            String s = (String) msg.obj; 
            tv.setText(data); 
           } ... //other IFs? 
          } 
      

    IMHO, संदेश के लिए रास्ता नहीं हैं जाओ क्योंकि:

    • नए गैर-एंड्रॉइड प्रोग्रामर के लिए समझना आसान नहीं है (निर्माण के दौरान हैंडलर हैंडल हुक)।
    • संदेश पेलोड प्रक्रिया को पार करने पर ऑब्जेक्ट पेलोड को पार करने योग्य होना चाहिए।
    • संदेश पुन: उपयोग किया जाता है (त्रुटियों की संभावना अगर ठीक से साफ नहीं?)
    • हैंडलर दोहरी भूमिका (यह संदेश भेजता है, लेकिन यह भी उन्हें संभालती है)
    • संदेश गुण सार्वजनिक कर रहे हैं, लेकिन यह भी प्रदान करते हैं गेटर/सेटर है।

    दूसरी तरफ, रननेबल्स प्रसिद्ध ज्ञात पैटर्न का पालन करते हैं, और अधिक प्रोग्रामर-अनुकूल और पठनीय हैं।

    तो रननेबल्स पर संदेशों का उपयोग करने के क्या फायदे हैं? क्या आधुनिक दिन एंड्रॉइड प्रोग्रामिंग में संदेश पृष्ठभूमि में धकेल गए हैं? क्या ऐसा कुछ है जो आप संदेशों के साथ कर सकते हैं जो Runnables के साथ नहीं किया जा सकता है?

    अग्रिम धन्यवाद।

  • उत्तर

    4

    Handler इंटरफ़ेस डॉक्स के अनुसार, runOnUiThread() की तुलना में अधिक सुविधा प्रदान करता है:

    एक हैंडलर के दो मुख्य उपयोग कर रहे हैं:
    (1) शेड्यूल करने के लिए संदेश और runnables में कुछ बिंदु के रूप में क्रियान्वित किया जाना भविष्य
    (2) अपने आप से अलग थ्रेड पर प्रदर्शन करने के लिए एक क्रिया को लागू करने के लिए।

    runOnUiThread केवल (2) का उप-समूह करता है।यानी "enqueue एक कार्रवाई यूआई धागा पर करने" तो IMO

    जब तक आप की जरूरत है उन अतिरिक्त सुविधाओं runOnUiThread पर्याप्त और पसंदीदा तरीका है।

    +0

    ठीक है, शायद विचार मेरे प्रश्न में स्पष्ट रूप से सामने नहीं आया है। यह हैंडलर बनाम Runnables नहीं है, लेकिन Handler.sendMessage रननेबल विकल्प बनाम। (इस समूह में 'हैंडलर.postDelayed' और' हैंडलर.postAtTime' भी शामिल है जो # 1) –

    +0

    आपने वास्तव में अपनी पोस्ट में अंतर को समझाया। मुझे कोई अन्य अंतर नहीं पता है जिसे मैं जोड़ सकता हूं। – Caner

    12

    Messages पुन: उपयोग किया जा सकता है, इसलिए इसके परिणामस्वरूप कम वस्तुओं और कम जीसी में परिणाम होता है। आप कम कक्षाओं और गुमनाम प्रकारों के साथ भी समाप्त होते हैं।

    एक बड़ा फायदा यह है कि Message को Handler पर भेजने वाली कक्षा को Message के कार्यान्वयन के बारे में कुछ भी जानने की आवश्यकता नहीं है। यह उस स्थान के आधार पर encapsulation में सहायता कर सकता है जहां इसका उपयोग किया जाता है।

    अंत में, आप doStuff() करने के लिए होगा जहां

    mHandler.obtainMessage(DO_STUFF, foo).sendToTarget(); 
    

    बनाम

    final Foo tempFoo = foo; 
    mHandler.post(new Runnable(){ 
        @Override 
        public void run(){ 
         doStuff(tempFoo); 
        } 
    }; 
    

    आप कई स्थानों है, तो के बीच सफाई में अंतर पर विचार पूर्व ज्यादा अधिक पठनीय है और आपको कम होगा कोड डुप्लिकेशन।

    +3

    रननेबल्स का पुन: उपयोग भी किया जा सकता है, यह एक इंटरफेस भी है और आप दिखाए गए एक से क्लीनर तरीके से एक को तत्काल कर सकते हैं (जो मैंने पोस्ट किया है :))। –

    +1

    एफडब्ल्यूआईडब्ल्यू मुझे लगता है कि यहां कुंजी यह है कि संदेशों को कक्षा के निर्माण की आवश्यकता नहीं होती है/संदेश भेजने के तरीके के बारे में कुछ भी जानने के लिए उन्हें भेजना पड़ता है।यह एक क्लाइंट को बेनकाब करने का एक तरीका है कि आप चाहते हैं कि वे आपको कुछ जानकारी भेजें, लेकिन इसके साथ क्या नहीं किया जाएगा। यह आसान भी है यदि आप संदेशों को उत्पन्न करने वाले कोड के साथ गड़बड़ किए बिना रन टाइम पर विभिन्न हैंडलरों में स्वैप करने में सक्षम होना चाहते हैं। तो पोस्ट किए गए प्रश्न के मामले में, इस तरह का एक साधारण यूआई अपडेट एक संदेश या एक रननेबल के बराबर है। लेकिन निश्चित रूप से ऐसे मामले हैं जहां संदेश अतिरिक्त लाभ प्रदान करते हैं। –

    +0

    मुख्य कारण यह है कि संदेश उपयोगी क्यों होंगे क्योंकि एंड्रॉइड ओएस वास्तव में उन्हें कतारबद्ध करता है, इसलिए किसी भी समय आप यह सुनिश्चित कर सकते हैं कि बाद में भेजे गए संदेश केवल भेजे गए संदेशों को निष्पादित किए जाने के बाद ही निष्पादित किए जाएंगे। – Bhargav

    17

    मैं कहूंगा कि Message बनाम Runnable का उपयोग करने के बीच थोड़ा अंतर है। यह ज्यादातर व्यक्तिगत वरीयता के लिए उबाल जाएगा। क्यूं कर? स्रोत कोड को देखते हुए आप पाएंगे कि Runnable पोस्ट करना एक ही सटीक संदेश तंत्र का उपयोग करता है। यह बस Runnable को Message से जोड़ता है और उसे भेजता है।

    4.4.2 स्रोत कोड

    public final boolean post(Runnable r) { 
        return sendMessageDelayed(getPostMessage(r), 0); 
    } 
    
    private static Message getPostMessage(Runnable r) { 
        Message m = Message.obtain(); 
        m.callback = r; 
        return m; 
    } 
    

    रेफरी: Grep Code - Handler

    +0

    हाय क्या आप पुष्टि कर सकते हैं जब हमें हैंडल मैसेज विधि को लागू करने की आवश्यकता है? मेरा मतलब है जब हमें हैंडलर की बाल कक्षा की आवश्यकता होती है? क्योंकि हम हैंडलरपोस्ट(); को कॉल करके मुख्य यूआई थ्रेड में संवाद भेज सकते हैं; तरीका। – UnKnown

    +0

    पोस्ट करने का सुझाव दें कि एक नए प्रश्न के रूप में –

    +0

    यहां मैंने एक नया प्रश्न बनाया है। https://stackoverflow.com/questions/47336380/when-we-need-to-override-handlers-handlemessage-method – UnKnown

    1

    मैं Message करने के लिए Runnable पसंद करते हैं। मुझे लगता है कि Runnable का उपयोग कर कोड Message से बहुत स्पष्ट है, क्योंकि ईवेंट हैंडलिंग कोड ईवेंट के बहुत करीब है। इसके अलावा, आप स्थिरांक को परिभाषित करने और मामलों को स्विच करने के ऊपरी हिस्से से बच सकते हैं।

    और मुझे नहीं लगता कि Runnable का उपयोग करके encapsulation का उल्लंघन करता है। आप Runnable.run() में बाहरी वर्ग में किसी अन्य विधि में कोड निकाल सकते हैं, उदाहरण के लिए on...Event(), या इसे EventHandler ऑब्जेक्ट में भी लपेटें। Message का उपयोग करने के अलावा दोनों तरीकों से अधिक स्पष्ट हैं, खासकर जब आपको Message में स्टोर संदर्भों की आवश्यकता होती है, क्योंकि Runnable का उपयोग msg.obj डाउनकास्टिंग से बचाता है। और नामहीन क्षेत्र msg.obj भी त्रुटि प्रवण है और कभी-कभी समझने में अक्षम है।

    और Runnable को इसे एक फ़ील्ड के रूप में संग्रहीत करके पुन: उपयोग किया जा सकता है।

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