Android: मुझे एक हैंडलर () का उपयोग कब करना चाहिए और मुझे थ्रेड का उपयोग कब करना चाहिए?


129

जब मुझे एसिंक्रोनस रूप से चलाने के लिए किसी चीज की आवश्यकता होती है , जैसे कि लंबे समय तक चलने वाला कार्य या एक तर्क जो नेटवर्क का उपयोग करता है, या जो भी कारण, एक नया थ्रेड शुरू करना और इसे चलाना ठीक काम करता है। एक हैंडलर बनाना और इसे चलाना भी काम करता है। क्या फर्क पड़ता है? मुझे हर एक का उपयोग कब करना चाहिए? A Handlerऔर a का उपयोग करने के क्या फायदे / कारण हैं Thread?

पुनश्च। - इस सवाल के लिए, आइए अनदेखा करें AsyncTask। - Handler().postDelayedउपयोग मामला मेरे लिए स्पष्ट है, इस प्रश्न के लिए मान लें कि मुझे तुरंत काम शुरू करने की आवश्यकता है।


आपकी स्थिति में बस सीधे आगे बढ़ें और एक नए थ्रेड का उपयोग करें, मेरा अगला सुझाव होगा AsyncTask लेकिन यह वह नहीं है जो आप स्पष्ट रूप से चाहते हैं। हैंडलर ज्यादातर उपयोग किए जाते हैं यदि आप विलंब या किसी अन्य प्रकार के अनुकूलन को किसी रन करने योग्य में जोड़ना चाहते हैं।
काबुतो 178

1
@ kabuto178 अच्छी तरह से, हैंडलर के अन्य लाभ हैं जो ध्यान देने योग्य हैं कि आप छोड़ दिया है। जैसे, एक अलग थ्रेड से यूआई थ्रेड के साथ बातचीत करने में सक्षम होना ..
tony9099

जवाबों:


168

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

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

एक विशिष्ट थ्रेड / हैंडलर इंटरैक्शन कुछ इस तरह दिख सकता है:

Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        if(msg.what == 0){
            updateUI();
        }else{
            showErrorDialog();
        }
    }
};

Thread t = new Thread() {
    @Override
    public void run(){
        doSomeWork();
        if(succeed){
            //we can't update the UI from here so we'll signal our handler and it will do it for us.
            h.sendEmptyMessage(0);
        }else{
            h.sendEmptyMessage(1);
        }
    }   
};

हालांकि, सामान्य तौर पर, घर ले जाता है कि आप किसी भी समय एक थ्रेड का उपयोग करें जो आप कुछ काम कर रहे हैं जो लंबे समय तक चल सकता है या बहुत गहन हो सकता है (यानी कुछ भी नेटवर्क, फ़ाइल आईओ, भारी गणित आदि)।


त्वरित उत्तर और निवेश की गई राशि की मात्रा के लिए धन्यवाद (और आपके उत्तर की गति !!)! तो, मुझे यह देखने दें कि क्या मुझे यह मिला है: हैंडलर को कार्यकर्ता थ्रेड्स और यूआई थ्रेड के बीच गैर-अवरुद्ध संचार की सुविधा के लिए बनाया गया है?
JRun

3
@JRun यह हां में से एक है। इसके बारे में कुछ बेहतरीन जानकारी के लिए जावा डॉक्स में हैंडलर विवरण देखें । इसके उपयोगों में से एक (भविष्य में कुछ बिंदु के रूप में निष्पादित किए जाने वाले संदेशों और रनवे को शेड्यूल करने के लिए)।
फामुगी

अच्छी तरह से समझाया @FoamyGuy!
tony9099

नमस्ते, क्या यह गारंटी है कि (नए विचारों को लोड किए जाने के updateUI()बाद onCreateView) चलेगा ?
जिउ डे Z

1
क्यों है message.what()? यह सिर्फ नहीं होगा if(msg == 0){? बहुत बहुत धन्यवाद! :)
रुचिर बैरोनिया

64

हैंडलर और थ्रेड वास्तव में 2 अलग चीजें हैं।

लंबी चलने वाली नौकरियों को निष्पादित करने के लिए एक धागा बनाया जाना चाहिए।

एक हैंडलर 2 थ्रेड्स के बीच संचार करने के लिए बहुत सुविधाजनक ऑब्जेक्ट है (उदाहरण के लिए: UI को अपडेट करने के लिए एक बैकग्राउंड थ्रेड की आवश्यकता है। आप अपने बैकग्राउंड थ्रेड से UI थ्रेड में कुछ Runnable पोस्ट करने के लिए हैंडलर का उपयोग कर सकते हैं)।

इसलिए आपके पास हैंडलर या थ्रेड के बीच कोई विकल्प नहीं है। भारी काम करने के लिए एक धागे का उपयोग करें! (आप एक हैंडलर का उपयोग कर सकते हैं यदि आपका बैकग्राउंड थ्रेड किसी अन्य थ्रेड में किए जाने वाले काम को ट्रिगर करेगा - अधिकांश समय यूआई थ्रेड)


त्वरित उत्तर और निवेश की गई राशि की मात्रा के लिए धन्यवाद (और आपके उत्तर की गति !!)!
JRun

28

Handlerऔर Threadदो अलग-अलग चीजें हैं, लेकिन वे एक-दूसरे के विपरीत नहीं हैं। आपके पास एक ही समय में एक Handlerऔर एक Threadहो सकता है और वास्तव में प्रत्येक Handlerको एक में चलना चाहिए Thread

अधिक जानकारी के लिए, आप इस लेख को देख सकते हैं ।

यहाँ छवि विवरण दर्ज करें


19

एक Handlerही पर रन Thread, एक Threadएक अलग धागे पर चलाता है।

यदि आपको एक ही धागे पर कुछ चलाने की आवश्यकता है, तो एक हैंडलर का उपयोग करें , तो आमतौर पर एक GUI तत्व या ऐसा कुछ।

यदि आप मुख्य थ्रेड को अन्य चीजों को करने के लिए स्वतंत्र रखना चाहते हैं, तो एक थ्रेड का उपयोग करें । किसी भी महत्वपूर्ण समय के लिए इसका उपयोग करें।


6
अगर मैं एक ही धागे पर कुछ चलाना चाहता हूं तो मुझे हैंडलर का उपयोग क्यों करना चाहिए? mHandler.post (...) विधि का उद्देश्य क्या है?
एलियास

1
एलियास, इस तरह के मामले में, आप हैंडलर का उपयोग कर सकते हैं यदि आप एक निश्चित कार्य के लिए एक निश्चित समय के बाद चलना चाहते हैं, या हर एक्स राशि के एक कार्य को दोहराना चाहते हैं। यदि आप इन चीजों का उपयोग नहीं करना चाहते हैं, तो आप सही हैं। हैंडलर का उपयोग करना अयोग्य है। आप बस GUI चीजें वहीं कर सकते हैं और फिर, bcoz आप किसी भी तरह UI थ्रेड में हैं, क्योंकि हैंडलर उस थ्रेड पर चलता है जिसमें यह बनाया गया था।
tony9099

14

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

उपयोग:

थ्रेड: UI थ्रेड की तुलना में स्पैक्ट्रेट (पृष्ठभूमि) थ्रेड में कार्य करने के लिए। (UI थ्रेड को अनब्लॉक करने में मदद करता है)

हैंडलर यूआई और बैकग्राउंड थ्रेड के बीच संवाद करता था।

इस लेख पर एक नज़र डालें


4

यदि आपको नए थ्रेड से उपयोगकर्ता इंटरफ़ेस को अपडेट करने की आवश्यकता है, तो आपको उपयोगकर्ता इंटरफ़ेस थ्रेड के साथ सिंक्रनाइज़ करने की आवश्यकता है।

आप इसके लिए android.os.Handler वर्ग या AsyncTasks वर्ग का उपयोग कर सकते हैं।

हैंडलर वर्ग यूजर इंटरफेस को अपडेट कर सकता है। एक हैंडलर संदेश या Runnable वर्ग के उदाहरण प्राप्त करने के लिए तरीके प्रदान करता है।

आप sendMessage (संदेश संदेश) विधि के माध्यम से या sendEmptyMessage () विधि के माध्यम से संदेश पोस्ट कर सकते हैं।

... और अधिक जानकारी यहाँ धागे आदि के बारे में (जब क्या उपयोग करने के लिए अलग अलग सूत्रण और सिंक तंत्र के लिए turorials और भी शामिल है)


मेरे प्रश्न का उत्तर देने के लिए समय निकालने के लिए धन्यवाद। मैं लार्स वोगेल के ब्लॉग से प्यार करता हूं, यह बहुत ही आनंददायक है और इसका पालन करना आसान है। धन्यवाद!
JRun

2

हैंडलर और थ्रेड का उपयोग करने के क्या फायदे / कारण हैं?

एक हैंडलर आपको Runnableएक थ्रेड से जुड़े संदेश और ऑब्जेक्ट भेजने और संसाधित करने की अनुमति देता है MessageQueue। प्रत्येक Handlerउदाहरण एक धागे से जुड़ा होता है और उस धागे की संदेश कतार।

जब आप एक नया बनाते हैं Handler , तो यह उस थ्रेड के थ्रेड / मैसेज कतार के लिए बाध्य होता है, जो इसे बना रहा है - उस बिंदु से, यह मैसेज और रनवेबल्स को उस मैसेज कतार तक पहुंचाएगा और उन्हें मैसेज क्यू से बाहर आने पर निष्पादित करेगा। ।

हैंडलर के दो मुख्य उपयोग हैं:

  1. भविष्य में कुछ बिंदु के रूप में निष्पादित किए जाने वाले संदेशों और Runnables को शेड्यूल करने के लिए
  2. करने के लिए enqueue एक कार्रवाई अपनी खुद की तुलना में एक अलग धागा पर प्रदर्शन किया जाना है।

यदि आप जावा थ्रेड्स का उपयोग करते हैं, तो आपको अपने आप ही somethings को संभालना होगा - मुख्य धागे के साथ सिंक्रनाइज़ करना, एक धागा रद्द करना आदि।

यह सिंगल थ्रेड तब तक थ्रेड पूल नहीं बनाता है जब तक कि आप उपयोग ThreadPoolExecutorया ExecutorServiceएपीआई नहीं करते हैं।

(ब्लैकबेल्ट उत्तर पर अपनी टिप्पणियों से इस प्रश्न को लिया)

एक्सिक्यूटर का उपयोग क्यों नहीं किया जाता है? और यहां तक ​​कि अगर मैं ऐसा करने के लिए एक हैंडलर का उपयोग करना चाहता था, तो कैसे?

संदर्भ: थ्रेड प्रदर्शन लेख

कुछ प्रकार के कार्य हैं जिन्हें अत्यधिक समानांतर, वितरित कार्यों में घटाया जा सकता है। काम के पैकेट की सरासर मात्रा के साथ यह बनाता है, AsyncTaskऔर HandlerThreadउपयुक्त कक्षाएं नहीं हैं। एकल-थ्रेडेड प्रकृति AsyncTaskसभी थ्रेडेड कार्य को एक लीनियर सिस्टम में बदल देगी। HandlerThreadदूसरी ओर, कक्षा का उपयोग करना , प्रोग्रामर को थ्रेड्स के समूह के बीच लोड संतुलन को मैन्युअल रूप से प्रबंधित करने की आवश्यकता होगी।

ThreadPoolExecutor इस प्रक्रिया को आसान बनाने के लिए एक सहायक वर्ग है। यह वर्ग थ्रेड्स के एक समूह के निर्माण का प्रबंधन करता है, उनकी प्राथमिकताएं निर्धारित करता है, और उन थ्रेड्स के बीच काम कैसे वितरित किया जाता है, का प्रबंधन करता है। जैसे ही कार्यभार बढ़ता है या घटता है, वर्ग कार्यभार को समायोजित करने के लिए अधिक थ्रेड्स को नष्ट या नष्ट कर देता है।

 BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
 ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

आप अधिक विवरण के लिए इस थ्रेड गाइड पर डेवलपर गाइड लेख का उल्लेख कर सकते हैं ।

Handlerकई रन करने योग्य उदाहरणों को चलाने के उपयोग के लिए इस पोस्ट पर एक नज़र डालें । इस स्थिति में, सभी Runnableकार्य एक ही थ्रेड में चलेंगे।

Android: एक धागे में टोस्ट


1

HandlerThreadएक कतार तंत्र बनाने के लिए संयोजन के रूप में इस्तेमाल किया जा सकता है। यूओ handlerपर कुछ पोस्ट करने के लिए उपयोग कर सकते हैंThread Looper


मेरे प्रश्न का उत्तर देने के लिए समय निकालने के लिए धन्यवाद। एक्सिक्यूटर का उपयोग क्यों नहीं किया जाता है? और यहां तक ​​कि अगर मैं ऐसा करने के लिए एक हैंडलर का उपयोग करना चाहता था, तो कैसे?
JRun

निष्पादक थोड़ा अलग है। इसका उपयोग करने के लिए आपको थ्रेड का विस्तार करना होगा और रन कॉल में static.metohd तैयार होगा। लूपर वर्ग को। स्टैटिक मेथड लूप को कॉल करने के बाद एक कतार बनाई जाती है और आप रिक्वेस्ट करने के लिए हैंडलरबिन ऑर्डर का उपयोग कर सकते हैं और परिणाम वापस पा सकते हैं
Blackbelt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.