किसी सेवा से UI थ्रेड हैंडलर तक पहुँचना


90

मैं एंड्रॉइड पर कुछ नया करने की कोशिश कर रहा हूं, जिसके लिए मुझे यूआई थ्रेड के हैंडलर तक पहुंचने की आवश्यकता है।

मुझे निम्नलिखित पता है:

  1. UI थ्रेड का अपना हैंडलर और लूपर है
  2. किसी भी संदेश को UI थ्रेड की संदेश कतार में रखा जाएगा
  3. लूपर घटना को उठाता है और इसे हैंडलर को पास करता है
  4. हैंडलर संदेश को संभालता है और यूएफ को विशेषांक भेजता है

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

मैं जानना चाहूंगा कि क्या यह संभव है। यदि ऐसा है तो कृपया कुछ कोड स्निपेट सुझाएं, ताकि मैं इसे आजमा सकूं।

सादर गिरीश

जवाबों:


179

कोड का यह स्निपेट मुख्य (UI) थ्रेड से संबद्ध एक हैंडलर का निर्माण करता है:

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

फिर आप मुख्य (UI) थ्रेड में निष्पादन के लिए सामान पोस्ट कर सकते हैं जैसे:

handler.post(runnable_to_call_from_main_thread);

यदि हैंडलर स्वयं मुख्य (UI) थ्रेड से बनाया गया है तो तर्क को संक्षिप्तता के लिए छोड़ा जा सकता है:

Handler handler = new Handler();

एंड्रॉयड डेवलपर मार्गदर्शिका पर प्रक्रियाओं और धागे के बारे में अधिक जानकारी नहीं है।


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

1
प्रतिभाशाली। एक आकर्षण की तरह काम करता है, और बहुत उपयोगी है। धन्यवाद।
JRun

एकदम सही ^ ^ एक StreamingService से मेरे यूआई अद्यतन करने के लिए बस इसका इस्तेमाल किया। वास्तव में मुझे क्या चाहिए धन्यवाद!
एक Droid

क्या आप जानते हैं कि क्या मैं एक हैंडलर का एकल उदाहरण बना सकता हूं, और इसका उपयोग कर सकता हूं कि हर बार मुझे ui धागे पर कुछ चलाने की आवश्यकता है?
हेलोवर्ल्ड

मुझे लगता है कि हम कभी नहीं जान पाएंगे
डेनी

28

Messengerअपने से जुड़ी कोई वस्तु बनाएं Handlerऔर उसे पास Messengerकरें Service(जैसे, एक Intentअतिरिक्त के लिए startService())। Serviceफिर एक भेज सकते हैं Messageकरने के लिए Handlerके माध्यम से Messengerयहाँ एक नमूना अनुप्रयोग प्रदर्शित किया गया है।


इस टिप के लिए धन्यवाद। यह मददगार था। कृपया मेरी गतिविधि MyDemo.dispatchTouchEvent (MotionEvent) लाइन: 20 PhoneWindow $ DecorView.dispatchTouchEvent (MotionEvent) लाइन: 1696 Viewootoot.handleMessage (संदेश) लाइन: 1658 ViewRoot (हैंडलर)। संदेश का स्पर्श करें। ) लाइन: 99 Looper.loop () लाइन: 123 // ईवेंट हैंडलिंग यहां शुरू होती है ActivThread.main (स्ट्रिंग []) लाइन: 4203 यहां व्यूअरूट एक हैंडलर है। मैं इस हैंडलर का संदर्भ प्राप्त करना चाहता हूं ... क्या मेरे आवेदन से इसे प्राप्त करना संभव है?
iLikeAndroid 6

@ लाइकएंड्रॉयड: यदि आपने इसे नहीं बनाया है Handler, तो आप इसे एएफ़एआईसी तक नहीं पहुंचा सकते।
कॉमन्सवेअर

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

@ आईलाइकएंड्रॉयड: ViewRootएंड्रॉइड एसडीके, एएफएआईसीटी में कोई नहीं है।
कॉमन्सवेअर

1
@ hadez30: व्यक्तिगत रूप से, मैं बाध्य सेवाओं का उपयोग नहीं करता हूं। आप अभी भी a Handler/ का उपयोग करने के लिए स्वागत कर रहे हैं Messenger, हालांकि मैं एक इवेंट बस (उदाहरण के लिए, ग्रीनब्रोट्स इवेंटबस) के साथ वह सब बदलूंगा।
कॉमन्सवेयर

4

फिलहाल मैं इस तरह की समस्या के लिए ओटो जैसी इवेंट बस लाइब्रेरी का उपयोग करना पसंद करता हूं । बस वांछित घटकों (गतिविधि) की सदस्यता लें:

protected void onResume() {
    super.onResume();
    bus.register(this);
}

फिर कॉलबैक विधि प्रदान करें:

public void onTimeLeftEvent(TimeLeftEvent ev) {
    // process event..
}

और फिर जब आपकी सेवा इस तरह एक बयान को निष्पादित करती है:

bus.post(new TimeLeftEvent(340));

वह POJO आपकी उपरोक्त गतिविधि और अन्य सभी सदस्यता घटकों को पास किया जाएगा। सरल और सुरुचिपूर्ण।


3

मेरा सुझाव है कि निम्नलिखित कोड आज़माएं:

    new Handler(Looper.getMainLooper()).post(() -> {

        //UI THREAD CODE HERE



    });

ओपी की सहायता के लिए कुछ अतिरिक्त स्पष्टीकरण की आवश्यकता है।
मोग

2

आप प्रसारण रिसीवर के माध्यम से मान प्राप्त कर सकते हैं ...... निम्नानुसार, पहले अपना खुद का IntentFilter बनाएं,

Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");

फिर इनर ब्रॉडकास्टराइवर के रूप में इनर क्लास बनाएं।

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    /** Receives the broadcast that has been fired */
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction()=="YOUR_INTENT_FILTER"){
           //HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW///////////
           String receivedValue=intent.getStringExtra("KEY");
        }
    }
};

अब अपने प्रसारण रिसीवर को onResume () में पंजीकृत करें,

registerReceiver(broadcastReceiver, intentFilter);

और अंत में ऑनरगेस्टर में Unregister BroadcastReceiver (),

unregisterReceiver(broadcastReceiver);

अब सबसे महत्वपूर्ण हिस्सा ... आपको जहां भी मूल्यों को भेजने की आवश्यकता है, वहां से प्रसारण को आग लगाने की आवश्यकता है ..... इसलिए,

Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);

.... जयकार :)


1

में kotlinthats कैसे आप यह कर सकते

मान लें कि आप सेवा से टोस्ट संदेश दिखाना चाहते हैं

val handler = Handler(Looper.getMainLooper())
handler.post {
   Toast.makeText(context, "This is my message",Toast.LENGTH_LONG).show()
}

0

समाधान:

  1. मुख्य थ्रेड से Looper के साथ एक हैंडलर बनाएँ : requestHandler
  2. एक बनाएं Handlerसाथ Looperमुख्य थ्रेड से: responseHandler और ओवरराइड handleMessageविधि
  3. एक पोस्ट Runnable requestHandler पर काम
  4. Runnableकार्य के अंदर , responseHandler पर sendMessage को कॉल करें
  5. इस sendMessageप्रतिक्रिया में हैंडहेल्मेज का निमंत्रण है।
  6. से गुण प्राप्त करें Messageऔर इसे संसाधित, अद्यतन यूआई

नमूना कोड:

    /* Handler from UI Thread to send request */

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

     /* Handler from UI Thread to process messages */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {

            /* Processing handleMessage */

            Toast.makeText(MainActivity.this,
                    "Runnable completed with result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    for ( int i=0; i<10; i++) {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                   /* Send an Event to UI Thread through message. 
                      Add business logic and prepare message by 
                      replacing example code */

                    String text = "" + (++rId);
                    Message msg = new Message();

                    msg.obj = text.toString();
                    responseHandler.sendMessage(msg);
                    System.out.println(text.toString());

                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        };
        requestHandler.post(myRunnable);
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.