2012-09-27 7 views
37

मैं Handlers और runOnUiThread अवधारणाओं दोनों में आया हूं। लेकिन मेरे लिए यह अभी भी एक संदेह प्रतीत होता है कि वे किस तथ्य पर बिल्कुल भिन्न होते हैं।रनऑनयूआईट्रेड के दौरान हैंडलर का उपयोग क्यों करें?

वे दोनों पृष्ठभूमि थ्रेड से UI क्रियाएं करने का इरादा रखते हैं। लेकिन जब हम दो तरीकों में से चुनते हैं तो उन कारकों पर क्या विचार किया जाना चाहिए।

उदाहरण के लिए RunnableThread पर विचार करें जो पृष्ठभूमि में एक वेब सेवा करता है और अब मैं यूआई अपडेट करना चाहता हूं।

मेरे यूआई को अपडेट करने का सबसे अच्छा तरीका क्या होगा? क्या मुझे Handler या runOnUiThread के लिए जाना चाहिए?

मुझे अभी भी पता है कि मैं AsyncTask का उपयोग कर सकता हूं और onPostExecute का उपयोग कर सकता हूं। लेकिन मैं सिर्फ अंतर जानना चाहता हूं।

+2

'runOnUiThread' सिर्फ एक' Handler' करने के लिए एक 'Runnable' पोस्ट करने के लिए एक शॉर्टकट है। 'हैंडलर' एंड्रॉइड द्वारा परिभाषित प्रत्येक (?) क्रॉस-थ्रेड-संचार सुविधा का आधार है (उदाहरण के लिए 'AsyncTask'' onPostExecute' 'doInBackground' से परिणाम देने के लिए' हैंडलर 'का उपयोग करता है)। – zapl

उत्तर

63

Activity.runOnUiThread() अधिक सामान्य Handlers का एक विशेष मामला है। Handler के साथ आप अपने स्वयं के थ्रेड के भीतर अपनी खुद की घटना क्वेरी बना सकते हैं। Handlers का उपयोग default constructorके साथ तत्काल का मतलब नहीं है "कोड यूआई थ्रेड" सामान्य रूप से चलाया जाएगा। डिफ़ॉल्ट रूप से, हैंडलर Thread से बंधे होते हैं, जिससे उन्हें तत्काल से हटा दिया गया था।

Handler बनाने के लिए (मुख्य) धागा आप Handler वस्तु इस तरह के मुख्य Looper आबद्ध बनाना चाहिए यूआई के लिए बाध्य करने के लिए गारंटी है कि: यदि आप runOnuiThread() विधि के क्रियान्वयन की जांच,

Handler mHandler = new Handler(Looper.getMainLooper()); 

इसके अलावा, यह Handler उपयोग कर रहा है काम करने के लिए:

public final void runOnUiThread(Runnable action) { 
     if (Thread.currentThread() != mUiThread) { 
      mHandler.post(action); 
     } else { 
      action.run(); 
     } 
    } 

आप ऊपर कोड स्निपेट से देख सकते हैं, Runnable action exe ​​हो जाएगा तत्काल काटा गया, अगर runOnUiThread() को यूआई थ्रेड से बुलाया जाता है। अन्यथा, यह इसे Handler पर पोस्ट करेगा, जिसे कुछ बिंदु बाद निष्पादित किया जाएगा।

+0

देखें लेकिन "थ्रेड से नहीं, जिससे उन्हें तुरंत चालू किया गया था।" आमतौर पर यूआई धागा? –

+8

@ माइक, यह पूरी तरह से आपके कोड से निर्भर करता है। अक्सर हां, हैंडलर को मुख्य थ्रेड से तत्काल किया जाता है, लेकिन ऐसे कई मामले हैं जहां डेवलपर के पास 'हैंडलर' उदाहरण बनाते समय वर्तमान धागे के बारे में सटीक जानकारी नहीं है। इसलिए, डेवलपर को 'नए हैंडलर (Looper.getMainLooper()) का उपयोग करना चाहिए, अगर उसे गारंटी की आवश्यकता है कि हैंडलर मुख्य धागे में प्रदर्शन करेगा। – HitOdessit

+0

ने यह धन्यवाद दिया कि यह बहुत उपयोगी है। –

0

हैंडलर सामान करने का पुराना तरीका (एपीआई लेवल 1) थे, और AsycTask (एपीआई लेवल 3) को runOnUIThread (एपीआई लेवल 1) का उपयोग करने पर एक मजबूत फोकस के साथ पेश किया गया था। आपको जितना संभव हो सके हैंडलर का उपयोग करना चाहिए, और अपनी ज़रूरत के आधार पर अन्य दो को पसंद करना चाहिए।

+1

लेकिन क्यों? मुझे बिल्कुल अंतर की जरूरत है। क्या आप कृपया और बता सकते हैं। –

+0

कोई फर्क नहीं पड़ता है, आप हैंडलर और लूपर्स के साथ एक ही चीजें प्राप्त कर सकते हैं, लेकिन ये तकनीकें आपको गलतियों से बचने में मदद करती हैं। Http://en.wikipedia.org/wiki/Syntactic_sugar – Animesh

1

हैंडलर संदेश और बार-बार यूआई अद्यतन गुजर जैसे कई काम है अगर आप किसी भी एक काम ए हैंडलर आप भेजने के लिए और इस प्रक्रिया संदेश और एक थ्रेड MessageQueue ,, के साथ जुड़े Runnable वस्तुओं जो बहुत है की अनुमति देता है को चलाने का एक धागा शुरू ब्लूटूथ चैट ,, वाईफ़ाई बातचीत ... और हैंडलर जैसे कई आवेदन में उपयोगी है विधि PostDelay और PostAtTime के रूप में आप चेतन और परिवर्तन दृश्यता और इतने पर

आप इस

में ध्यान देना चाहिए करने के लिए किसी भी दृश्य के आसपास खेल सकते हैं जिसके द्वारा

http://developer.android.com/guide/components/processes-and-threads.html

http://developer.android.com/tools/testing/activity_testing.html

+0

हाँ, लेकिन यहां RunOnUIThread का उपयोग क्यों न करें? –

+1

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

1

HitOdessit के उत्तर के बाद।

आप इस तरह की एक कक्षा बना सकते हैं।

public class Global{ 
    private static Handler mHandler = new Handler(Looper.getMainLooper()); 
    public static void runOnUiThread(Runnable action){ 
     mHandler.post(action); 
    } 
} 

और फिर इसे इस तरह कॉल करें।

Global.runOnUiThread(new Runnable(){ 
    //Your code 
}); 

और यह कहीं से भी चलाया जा सकता है (जहां आपके पास अपनी वैश्विक कक्षा तक पहुंच है)।

0

मेरा यूआई अपडेट करने का सबसे अच्छा तरीका क्या होगा? क्या मुझे हैंडलर या रनऑनयू थ्रेड के लिए जाना चाहिए?

अपने Runnable जरूरतों यूआई अद्यतन करने के लिए है, यह runOnUiThread पर पोस्ट।

लेकिन यूआई थ्रेड पर Runnable पोस्ट करना हमेशा संभव नहीं होता है।

परिदृश्य के बारे में सोचें, जहां आपको निष्पादित करने की आवश्यकता है नेटवर्क/आईओ ऑपरेशन या वेब सेवा का आह्वान करें। इस मामले में, आप यूआई थ्रेड पर Runnable पोस्ट नहीं कर सकते हैं। यह android.os.NetworkOnMainThreadException

इस प्रकार का RunnableHandlerThread जैसे विभिन्न थ्रेड पर चलना चाहिए। अपना ऑपरेशन पूरा करने के बाद, आप Handler का उपयोग कर यूआई थ्रेड पर परिणाम पोस्ट कर सकते हैं, जो यूआई थ्रेड से जुड़ा हुआ है।

public void onClick(View view) { 

    // onClick on some UI control, perform Network or IO operation 

    /* Create HandlerThread to run Network or IO operations */ 
    HandlerThread handlerThread = new HandlerThread("NetworkOperation"); 
    handlerThread.start(); 

    /* Create a Handler for HandlerThread to post Runnable object */ 
    Handler requestHandler = new Handler(handlerThread.getLooper()); 

    /* Create one Handler on UI Thread to process message posted by different thread */ 

    final Handler responseHandler = new Handler(Looper.getMainLooper()) { 
     @Override 
     public void handleMessage(Message msg) { 
      //txtView.setText((String) msg.obj); 
      Toast.makeText(MainActivity.this, 
        "Runnable on HandlerThread is completed and got result:"+(String)msg.obj, 
        Toast.LENGTH_LONG) 
        .show(); 
     } 
    }; 

    NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler); 
    NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler); 
    requestHandler.post(r1); 
    requestHandler.post(r2); 

} 

class NetworkRunnable implements Runnable{ 
    String url; 
    Handler uiHandler; 

    public NetworkRunnable(String url,Handler uiHandler){ 
     this.url = url; 
     this.uiHandler=uiHandler; 
    } 
    public void run(){ 
     try { 
      Log.d("Runnable", "Before IO call"); 
      URL page = new URL(url); 
      StringBuffer text = new StringBuffer(); 
      HttpURLConnection conn = (HttpURLConnection) page.openConnection(); 
      conn.connect(); 
      InputStreamReader in = new InputStreamReader((InputStream) conn.getContent()); 
      BufferedReader buff = new BufferedReader(in); 
      String line; 
      while ((line = buff.readLine()) != null) { 
       text.append(line + "\n"); 
      } 
      Log.d("Runnable", "After IO call:"+ text.toString()); 

      Message msg = new Message(); 

      msg.obj = text.toString(); 

      /* Send result back to UI Thread Handler */ 
      uiHandler.sendMessage(msg); 


     } catch (Exception err) { 
      err.printStackTrace(); 
     } 
    } 
} 
संबंधित मुद्दे