ऐक्टिविटी के साथ एंड्रॉइड सर्विस का संचार कैसे करें


251

मैं अपना पहला एंड्रॉइड एप्लिकेशन लिख रहा हूं और सेवाओं और गतिविधियों के बीच संचार के चारों ओर अपना सिर पाने की कोशिश कर रहा हूं। मेरे पास एक सेवा है जो पृष्ठभूमि में चलेगी और कुछ जीपीएस और समय आधारित लॉगिंग करेगी। मेरे पास एक गतिविधि होगी जिसका उपयोग सेवा को शुरू करने और रोकने के लिए किया जाएगा।

इसलिए सबसे पहले, मुझे यह पता लगाने में सक्षम होना चाहिए कि गतिविधि शुरू होने पर सेवा चल रही है या नहीं। उस बारे में यहां कुछ अन्य प्रश्न हैं, इसलिए मुझे लगता है कि मैं इसका पता लगा सकता हूं (लेकिन सलाह देने के लिए स्वतंत्र महसूस करता हूं)।

मेरी वास्तविक समस्या: यदि गतिविधि चल रही है और सेवा शुरू हो गई है, तो मुझे सेवा के लिए गतिविधि के लिए संदेश भेजने का एक तरीका चाहिए। साधारण स्ट्रिंग्स और पूर्णांक इस बिंदु पर - स्थिति संदेश ज्यादातर। संदेश नियमित रूप से नहीं होंगे, इसलिए मुझे नहीं लगता कि यदि कोई अन्य तरीका है तो सेवा को मतदान करना एक अच्छा तरीका है। मैं केवल यह संचार चाहता हूं जब गतिविधि उपयोगकर्ता द्वारा शुरू की गई है - मैं सेवा से गतिविधि शुरू नहीं करना चाहता हूं। दूसरे शब्दों में, यदि आप गतिविधि शुरू करते हैं और सेवा चल रही है, तो आपको गतिविधि UI में कुछ दिलचस्प संदेश दिखाई देंगे जब कुछ दिलचस्प होगा। यदि आप गतिविधि शुरू नहीं करते हैं, तो आप इन संदेशों को नहीं देखेंगे (वे दिलचस्प नहीं हैं)।

ऐसा लगता है कि मुझे यह निर्धारित करने में सक्षम होना चाहिए कि क्या सेवा चल रही है, और यदि हां, तो गतिविधि को एक श्रोता के रूप में जोड़ें। जब गतिविधि रुक ​​जाती है या रुक जाती है तो गतिविधि को एक श्रोता के रूप में हटा दें। क्या यह वास्तव में संभव है? जिस तरह से मैं यह पता लगाने के लिए कर सकता हूं कि गतिविधि को पार्सेबल लागू करना और एआईडीएल फ़ाइल का निर्माण करना है ताकि मैं इसे सेवा के दूरस्थ इंटरफ़ेस के माध्यम से पारित कर सकूं। हालांकि यह ओवरकिल की तरह लगता है, और मुझे नहीं पता कि गतिविधि को कैसे लिखना चाहिए ।TTPParcel () / readFromParcel ()।

क्या कोई आसान या बेहतर तरीका है? किसी भी मदद के लिए धन्यवाद।

संपादित करें:

जो कोई भी बाद में इसमें रुचि रखता है, उसके लिए नमूना निर्देशिका में AIDL के माध्यम से इसे संभालने के लिए Google से नमूना कोड है: /apis/app/RemoteService.java

जवाबों:


94

सेवाओं के साथ संवाद करने के तीन स्पष्ट तरीके हैं:

  1. इरादों का उपयोग करना
  2. एआईडीएल का उपयोग करना
  3. स्वयं सेवा ऑब्जेक्ट का उपयोग करना (सिंगलटन के रूप में)

आपके मामले में, मैं विकल्प 3 के साथ जाऊंगा। यह उस सेवा के लिए एक स्थिर संदर्भ बनाएं जिसे वह स्वयं करता है और इसे ऑनक्रिएट () में पॉप्युलेट करता है:

void onCreate(Intent i) {
  sInstance = this;
}

एक स्थिर कार्य करें MyService getInstance(), जो स्थैतिक को लौटाता है sInstance

फिर Activity.onCreate()आप सेवा शुरू करते हैं, अतुल्यकालिक रूप से तब तक प्रतीक्षा करते हैं जब तक कि सेवा वास्तव में शुरू नहीं हो जाती है (आप अपनी सेवा को अपने ऐप को सूचित कर सकते हैं जो गतिविधि के लिए एक इरादा भेजकर तैयार है।) और इसका उदाहरण प्राप्त करें। जब आपके पास उदाहरण होता है, तो अपनी सेवा श्रोता वस्तु को आपकी सेवा में पंजीकृत करें और आप सेट हो जाते हैं। नोट: गतिविधि के अंदर दृश्य संपादित करते समय आपको उन्हें UI थ्रेड में संशोधित करना चाहिए, सेवा संभवतः अपना स्वयं का थ्रेड चलाएगी, इसलिए आपको कॉल करने की आवश्यकता है Activity.runOnUiThread()

आखिरी चीज जो आपको करने की ज़रूरत है वह है कि आप श्रोता ऑब्जेक्ट के संदर्भ को हटा दें Activity.onPause(), अन्यथा आपकी गतिविधि का एक उदाहरण लीक हो जाएगा, अच्छा नहीं।

नोट: यह विधि केवल तभी उपयोगी है जब आपका एप्लिकेशन / गतिविधि / कार्य एकमात्र प्रक्रिया है जो आपकी सेवा तक पहुंच बनाएगी। यदि ऐसा नहीं है तो आपको विकल्प 1 या 2 का उपयोग करना होगा।


2
मैं busy-waitगतिविधि कैसे कर सकता हूं ? क्या आप कृपया समझा सकते हैं?
iTurki

1
इसलिए या तो onCreate के बाद या onStartCommand के बाद आपकी सर्विस क्लास में एक पब्लिक स्टैटिक वेरिएबल सेट करें, कॉल करें कि यह कनेक्ट किया गया है या कुछ सच है। फिर अपनी गतिविधि में ऐसा करें: इरादा इरादा = नया इरादा (अधिनियम, YourService.class); startService (आशय); जबकि (! YourService.isConnected) {नींद (300); } उस लूप के बाद आपकी सेवा चल रही है और आप इसके साथ संचार कर सकते हैं .. मेरे अनुभव में निश्चित रूप से इस तरह की सेवा के साथ बातचीत करने की कुछ सीमाएं हैं।
मैट वोल्फ

इसे केवल में ही क्यों शुरू किया जा सकता है Activity.onCreate()?
स्काईवैल

कोई भी शब्द क्यों आप उनके बीच संदेशों के Intentsमाध्यम से डेटा भेजकर उपयोग नहीं करना चाहेंगे Parcellable?
अमन आलम

2
यह काम करता है, लेकिन @ मैक्सगायत का जवाब ज्यादा साफ-सुथरा है और इसमें कोई व्यस्तता नहीं है।
मैट

262

पूछने वाला शायद इस अतीत से आगे बढ़ा है, लेकिन मामले में कोई और इसके लिए खोज करता है ...

इसे संभालने का एक और तरीका है, जो मुझे लगता है कि सबसे सरल हो सकता है।

BroadcastReceiverअपनी गतिविधि में जोड़ें । इसमें कुछ कस्टम आशय प्राप्त करने के लिए इसे पंजीकृत करें onResumeऔर इसमें अपंजीकृत करें onPause। फिर अपनी सेवा से उस आशय को भेजें जब आप अपना स्टेटस अपडेट भेजना चाहते हैं या आपके पास क्या है।

सुनिश्चित करें कि यदि कोई अन्य ऐप आपके लिए सुने Intent(क्या कोई दुर्भावनापूर्ण काम कर सकता है?) तो आप दुखी नहीं होंगे , लेकिन इससे परे, आपको ठीक होना चाहिए।

कोड नमूना का अनुरोध किया गया था:

मेरी सेवा में, मेरे पास यह है:

// Do stuff that alters the content of my local SQLite Database
sendBroadcast(new Intent(RefreshTask.REFRESH_DATA_INTENT));

( RefreshTask.REFRESH_DATA_INTENTबस एक निरंतर स्ट्रिंग है।)

मेरी सुनने की गतिविधि में, मैं अपने को परिभाषित करता हूं BroadcastReceiver:

private class DataUpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(RefreshTask.REFRESH_DATA_INTENT)) {
          // Do stuff - maybe update my view based on the changed DB contents
        }
    }
}

मैं कक्षा के शीर्ष पर अपना रिसीवर घोषित करता हूं:

private DataUpdateReceiver dataUpdateReceiver;

मैं onResumeइसे जोड़ने के लिए ओवरराइड करता हूं :

if (dataUpdateReceiver == null) dataUpdateReceiver = new DataUpdateReceiver();
IntentFilter intentFilter = new IntentFilter(RefreshTask.REFRESH_DATA_INTENT);
registerReceiver(dataUpdateReceiver, intentFilter);

और मैं onPauseजोड़ने के लिए ओवरराइड करता हूं :

if (dataUpdateReceiver != null) unregisterReceiver(dataUpdateReceiver);

अब मेरी गतिविधि मेरी सेवा के लिए कह रही है "अरे, अपने आप को अपडेट करें।" मैं Intentडेटाबेस टेबलों को अपडेट करने के बजाय डेटा को पास कर सकता था और फिर अपनी गतिविधि के भीतर परिवर्तनों को खोजने के लिए वापस जा सकता था, लेकिन जब से मैं चाहता हूं कि परिवर्तन वैसे भी बने रहें, तो डेटा को डीबी के माध्यम से पारित करने के लिए समझ में आता है।


5
कैसे? आप जो वर्णन करते हैं वह वही है जिसकी मुझे आवश्यकता है। लेकिन इससे भी ज्यादा, मुझे पूरा नमूना कोड चाहिए। अग्रिम में धन्यवाद। FYI करें, पिछली बार जब मैंने एक विजेट लिखने की कोशिश की थी, तो संदेश भेजने वाले हिस्से में मुझे 2 महीने लगे। यदि आप चाहते हैं, तो हंसें, लेकिन आपको विशेषज्ञों को अधिक प्रकाशित करने की आवश्यकता है क्योंकि IMHO Android iOS की तुलना में अधिक जटिल है!

1
आआआआआआ, द व्यस्त कोडर गाइड टू एडवांस एंड्रॉइड डेवलपमेंट का विजेट्स पर एक उत्कृष्ट अध्याय है। यह एकमात्र संसाधन है जो मुझे उस गड़बड़ के माध्यम से मिला। कॉमन्सवेयर, लेखक, स्टैकऑवरफ़्लो पर 115k प्रतिष्ठा है, और मैं पुस्तक की अत्यधिक अनुशंसा करता हूं। commonsware.com/AdvAndroid
19

64
Broadcastsशानदार और इसके अलावा अगर आप अपने प्रसारण को अपनी प्रक्रिया से आगे नहीं बढ़ाना चाहते हैं, तो इस पर विचार करें LocalBroadcast: developer.android.com/reference/android/support/v4/content/…
कोडी कॉगलन

2
धन्यवाद कोडी, मैंने पहले नहीं देखा था।
अधिकतम

3
यह संचार का बहुत अच्छा तरीका है। लेकिन जब मामले को रोक दिया गया था, तो परिणाम क्या करना था? तो onResume गतिविधि के बाद परिणामों के लिए लंबे समय तक इंतजार कर सकते हैं। और कोई डेटा प्राप्त नहीं किया जाएगा, क्योंकि डेटा चूक गए थे।
एंटोन-एम

39

LocalBroadcastManagerअपने ऐप के अंदर स्थानीय सेवा से भेजे गए प्रसारण को सुनने के लिए एक रिसीवर को पंजीकृत करने के लिए उपयोग करें , संदर्भ यहां दिया गया है:

http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html


3
हां, लोकलब्रॉडकास्ट के बारे में एक बहुत अच्छी चर्चा यहां लिंक पर है
सोहेलअज़ीज़

1
LocalBroadcastManagerअब LiveDataया अन्य प्रेक्षक पैटर्न टूल्स के पक्ष में पदावनत किया गया है : developer.android.com/reference/androidx/localbroadcastmanager/…
अली नेम

20

मुझे आश्चर्य है कि किसी ने ओटो इवेंट बस लाइब्रेरी का संदर्भ नहीं दिया है

http://square.github.io/otto/

मैं अपने एंड्रॉइड ऐप में इसका उपयोग कर रहा हूं और यह मूल रूप से काम करता है।


7
वैकल्पिक रूप से, ग्रीनब्रोट की EventBus लाइब्रेरी है।
जज़्ज़ेर

15
लेकिन याद रखें कि EventBus और otto हमेशा एक प्रक्रिया में हैं। आप एक सेवा के लिए अपने स्वयं प्रक्रिया में है कि (सेट करना शुरू उपयोग कर रहे हैं जब android:process=":my_service"वे संवाद करने में सक्षम नहीं हैं।
रॉन

20

मैसेंजर का उपयोग करना सेवा और गतिविधि के बीच संवाद करने का एक और सरल तरीका है।

गतिविधि में, संबंधित मैसेंजर के साथ हैंडलर बनाएं। यह आपकी सेवा के संदेशों को संभाल लेगा।

class ResponseHandler extends Handler {
    @Override public void handleMessage(Message message) {
            Toast.makeText(this, "message from service",
                    Toast.LENGTH_SHORT).show();
    }
}
Messenger messenger = new Messenger(new ResponseHandler());

मैसेंजर को मैसेज में अटैच कर सर्विस को पास किया जा सकता है:

Message message = Message.obtain(null, MyService.ADD_RESPONSE_HANDLER);
message.replyTo = messenger;
try {
    myService.send(message);
catch (RemoteException e) {
    e.printStackTrace();
}

API डेमो में एक पूर्ण उदाहरण पाया जा सकता है: MessengerService और MessengerServiceActivity । MyService कैसे काम करता है के लिए पूरा उदाहरण देखें।


1
बहुत सराहना की! अच्छी तरह से काम। कोड में बस एक विवरण: इसके बजाय myService.send(message);होना चाहिए messenger.send(message);
फेडेरिको क्रिस्टीना

9

अन्य टिप्पणियों में उल्लिखित अन्य विधि को सेवा से बाइंड सर्विस () का उपयोग करते हुए सेवा में बाँधना है और सेवाकनेक्ट कॉलबैक में सेवा का एक उदाहरण प्राप्त करना है। जैसा कि यहाँ बताया गया है http://developer.android.com/guide/compenders/bound-services.html


4
यह सेवा उदाहरण का संदर्भ प्राप्त करने का सही तरीका है।
김준호

9

आप यह भी उपयोग कर सकते हैं LiveDataकि एक की तरह काम करता है EventBus

class MyService : LifecycleService() {
    companion object {
        var BUS = MutableLiveData<Object>()
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)

        val testItem : Object

        // expose your data
        if (BUS.hasActiveObservers()) {
            BUS.postValue(testItem)
        }

        return START_NOT_STICKY
    }
}

फिर अपने से एक पर्यवेक्षक जोड़ें Activity

MyService.BUS.observe(this, Observer {
    it?.let {
        // Do what you need to do here
    }
})

आप इस ब्लॉग से अधिक पढ़ सकते हैं


2

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


मैं इसी तरह की सोच से जूझ रहा हूं। मेरे पास गतिविधि और 2 सेवाएं हैं जिनमें समान मॉडल है। मॉडल को किसी भी गतिविधि या किसी भी सेवा में अपडेट किया जा सकता है, इसलिए मैंने किसी तरह ऑब्जर्वर का उपयोग करने के बारे में सोचा लेकिन यह पता नहीं लगा सका। क्या आप अपना विचार दिखाने के लिए उदाहरण पोस्ट कर सकते हैं?
pzo

2

मेरी विधि:

/ सेवा / गतिविधि से संदेश भेजने और प्राप्त करने का प्रबंधन करने के लिए कक्षा:

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MessageManager {

    public interface IOnHandleMessage{
        // Messages
        int MSG_HANDSHAKE = 0x1;

        void onHandleMessage(Message msg);
    }

    private static final String LOGCAT = MessageManager.class.getSimpleName();

    private Messenger mMsgSender;
    private Messenger mMsgReceiver;
    private List<Message> mMessages;

    public MessageManager(IOnHandleMessage callback, IBinder target){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_ACTIVITY));
        mMsgSender = new Messenger(target);
        mMessages = new ArrayList<>();
    }

    public MessageManager(IOnHandleMessage callback){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_SERVICE));
        mMsgSender = null;
        mMessages = new ArrayList<>();
    }

    /* START Getter & Setter Methods */
    public Messenger getMsgSender() {
        return mMsgSender;
    }

    public void setMsgSender(Messenger sender) {
        this.mMsgSender = sender;
    }

    public Messenger getMsgReceiver() {
        return mMsgReceiver;
    }

    public void setMsgReceiver(Messenger receiver) {
        this.mMsgReceiver = receiver;
    }

    public List<Message> getLastMessages() {
        return mMessages;
    }

    public void addMessage(Message message) {
        this.mMessages.add(message);
    }
    /* END Getter & Setter Methods */

    /* START Public Methods */
    public void sendMessage(int what, int arg1, int arg2, Bundle msgData){
        if(mMsgSender != null && mMsgReceiver != null) {
            try {
                Message msg = Message.obtain(null, what, arg1, arg2);
                msg.replyTo = mMsgReceiver;
                if(msgData != null){
                    msg.setData(msgData);
                }
                mMsgSender.send(msg);
            } catch (RemoteException rE) {
                onException(rE);
            }
        }
    }

    public void sendHandshake(){
        if(mMsgSender != null && mMsgReceiver != null){
            sendMessage(IOnHandleMessage.MSG_HANDSHAKE, 0, 0, null);
        }
    }
    /* END Public Methods */

    /* START Private Methods */
    private void onException(Exception e){
        Log.e(LOGCAT, e.getMessage());
        e.printStackTrace();
    }
    /* END Private Methods */

    /** START Private Classes **/
    private class MessageHandler extends Handler {

        // Types
        final static int TYPE_SERVICE = 0x1;
        final static int TYPE_ACTIVITY = 0x2;

        private IOnHandleMessage mCallback;
        private int mType;

        public MessageHandler(IOnHandleMessage callback, int type){
            mCallback = callback;
            mType = type;
        }

        @Override
        public void handleMessage(Message msg){
            addMessage(msg);
            switch(msg.what){
                case IOnHandleMessage.MSG_HANDSHAKE:
                    switch(mType){
                        case TYPE_SERVICE:
                            setMsgSender(msg.replyTo);
                            sendHandshake();
                            break;
                        case TYPE_ACTIVITY:
                            Log.v(LOGCAT, "HERE");
                            break;
                    }
                    break;
                default:
                    if(mCallback != null){
                        mCallback.onHandleMessage(msg);
                    }
                    break;
            }
        }

    }
    /** END Private Classes **/

}

गतिविधि उदाहरण में:

public class activity extends AppCompatActivity
      implements     ServiceConnection,
                     MessageManager.IOnHandleMessage { 

    [....]

    private MessageManager mMessenger;

    private void initMyMessenger(IBinder iBinder){
        mMessenger = new MessageManager(this, iBinder);
        mMessenger.sendHandshake();
    }

    private void bindToService(){
        Intent intent = new Intent(this, TagScanService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        /* START THE SERVICE IF NEEDED */
    }

    private void unbindToService(){
    /* UNBIND when you want (onDestroy, after operation...)
        if(mBound) {
            unbindService(mServiceConnection);
            mBound = false;
        }
    }

    /* START Override MessageManager.IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
        switch(msg.what){
            case Constants.MSG_SYNC_PROGRESS:
                Bundle data = msg.getData();
                String text = data.getString(Constants.KEY_MSG_TEXT);
                setMessageProgress(text);
                break;
            case Constants.MSG_START_SYNC:
                onStartSync();
                break;
            case Constants.MSG_END_SYNC:
                onEndSync(msg.arg1 == Constants.ARG1_SUCCESS);
                mBound = false;
                break;
        }
    }
    /* END Override MessageManager.IOnHandleMessage Methods */

    /** START Override ServiceConnection Methods **/
    private class BLEScanServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            initMyMessenger(iBinder);
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mMessenger = null;
            mBound = false;
        }
    }
    /** END Override ServiceConnection Methods **/

सेवा उदाहरण में:

public class Blablabla extends Service
    implements     MessageManager.IOnHandleMessage {

    [...]

    private MessageManager mMessenger;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        super.onBind(intent);
        initMessageManager();
        return mMessenger.getMsgReceiver().getBinder();
    }

    private void initMessageManager(){
        mMessenger = new MessageManager(this);
    }

    /* START Override IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
    /* Do what you want when u get a message looking the "what" attribute */
    }
    /* END Override IOnHandleMessage Methods */

गतिविधि / सेवा से एक संदेश भेजें:

mMessenger.sendMessage(what, arg1, arg2, dataBundle);

यह कैसे काम करता है:

जिस गतिविधि को आप शुरू करते हैं या सेवा को बांधते हैं। सेवा "OnBind" विधियाँ उसके संदेश प्रबंधक को Binder लौटाती हैं, गतिविधि में "सेवा कनेक्शन" इंटरफ़ेस विधियों के कार्यान्वयन के माध्यम से "OnServiceConnected" आपको यह IBinder मिलता है और इसका उपयोग करते हुए आपको MessageManager मिलता है। गतिविधि के बाद उसके MessageManager मैसेजहैंडलर सेंड और हैंडशेक को सेवा में इनिट कर देता है, ताकि वह अपने "MessageHandler" प्रेषक (MessageManager में "निजी मैसेंजर mMsgSender;") को सेट कर सके। इस सेवा को करने से पता चलता है कि किसने अपने संदेश भेजे।

आप संदेश प्रबंधक में मैसेंजर "प्रेषक" की एक सूची / कतार का उपयोग करके भी इसे लागू कर सकते हैं ताकि आप विभिन्न गतिविधियों / सेवाओं को कई संदेश भेज सकें या आप संदेश प्रबंधक में सूची / कतार "मैसेंजर" का उपयोग कर सकें ताकि आप कई प्राप्त कर सकें विभिन्न गतिविधियों / सेवाओं से संदेश।

"MessageManager" उदाहरण में आपके पास प्राप्त सभी संदेशों की एक सूची है।

जैसा कि आप "एक्टिविटी मैसेंजर" और "सर्विस मैसेंजर" के बीच के कनेक्शन को देख सकते हैं कि यह "मैसेजमैनेजर" उदाहरण ऑटोमैटिक है, यह "ऑनस्सेकनेक्टेड" विधि और "हैंडशेक" के उपयोग के माध्यम से किया जाता है।

आशा है कि यह आपके लिए उपयोगी है :) बहुत बहुत धन्यवाद! अलविदा: डी


2

कोड उदाहरण के साथ @MrSnowflake उत्तर पर अनुवर्ती कार्रवाई करने के लिए। यह XABBER अब खुला स्रोत Applicationवर्ग हैApplicationवर्ग को केंद्रीकृत करने और समन्वय है Listenersऔर ManagerInterfaces और अधिक। सभी प्रकार के प्रबंधकों को गतिशील रूप से लोड किया जाता है। Activity´sज़ैबर में शुरू की गई रिपोर्ट बताएगी कि Listenerवे किस प्रकार के हैं। और जब एक Serviceशुरुआत के रूप में यह Applicationकक्षा में रिपोर्ट करता है। अब एक के लिए एक संदेश भेजने के लिए Activityतुम सब करने की है है, तो अपने Activityएक हो जाते हैं listenerआप किस प्रकार की जरूरत की। में OnStart() OnPause()रजिस्टर / unreg टाइप करें। Serviceपूछ सकते हैं Applicationसिर्फ इतना है कि के लिए वर्ग listenerयह करने के लिए बात करने की जरूरत है और अगर यह वहाँ तो है गतिविधि प्राप्त करने के लिए तैयार है।

Applicationकक्षा के माध्यम से आप देखेंगे कि वहाँ एक लूट है और फिर यह चल रहा है।


प्रदान की गई कड़ी अब जीथब 404 में परिणत होती है। क्या यह चलती है?
जेई कार्टर II

हाँ, अब काम करने लगता है। जीथब पर एक अस्थायी मुद्दा रहा होगा।
जेई कार्टर II

1

बंधन एक और तरीका है संवाद करने का

एक कॉलबैक बनाएँ

public interface MyCallBack{

   public void getResult(String result);

}

गतिविधि पक्ष:

  1. गतिविधि में इंटरफ़ेस को लागू करें

  2. विधि के लिए कार्यान्वयन प्रदान करें

  3. सेवा के लिए गतिविधि को बांधें

  4. रजिस्टर और Unregister Callback जब सेवा बाध्य हो जाती है और गतिविधि के साथ अनबाउंड होती है।

    public class YourActivity extends AppCompatActivity implements MyCallBack{
    
          private Intent notifyMeIntent;
          private GPSService gpsService;
          private boolean bound = false;
    
          @Override
          public void onCreate(Bundle sis){
    
              // activity code ...
    
              startGPSService();
    
          }
    
          @Override
          public void getResult(String result){
           // show in textView textView.setText(result);
          }
    
          @Override
          protected void onStart()
          {
              super.onStart();
              bindService();
          }
    
          @Override
          protected void onStop() {
              super.onStop();
              unbindService();
          }
    
          private ServiceConnection serviceConnection = new ServiceConnection() {
    
                @Override
                public void onServiceConnected(ComponentName className, IBinder service) {
    
                      GPSService.GPSBinder binder = (GPSService.GPSBinder) service;
                      gpsService= binder.getService();
                      bound = true;
                      gpsService.registerCallBack(YourActivity.this); // register
    
               }
    
               @Override
               public void onServiceDisconnected(ComponentName arg0) {
                      bound = false;
               }
          };
    
          private void bindService() {
    
               bindService(notifyMeIntent, serviceConnection, Context.BIND_AUTO_CREATE);
          }
    
          private void unbindService(){
               if (bound) {
                     gpsService.registerCallBack(null); // unregister            
                     unbindService(serviceConnection);
                     bound = false;
                }
          }
    
          // Call this method somewhere to start Your GPSService
          private void startGPSService(){
               notifyMeIntent = new Intent(this, GPSService.class);
               startService(myIntent );
          }
    
     }

सेवा पक्ष:

  1. प्रारंभिक कॉलबैक

  2. जब भी जरूरत हो, कॉलबैक विधि लागू करें

     public class GPSService extends Service{
    
         private MyCallBack myCallback;
         private IBinder serviceBinder = new GPSBinder();
    
         public void registerCallBack(MyCallBack myCallback){
              this.myCallback= myCallback;
         }
    
         public class GPSBinder extends Binder{
    
             public GPSService getService(){
                  return GPSService.this;
             }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent){
             return serviceBinder;
        }
     }

अपने serviceConnectionसे बाहर है onCreate। कृपया इसे संपादित करें।
आदिल जफर


0

जैसा कि मधुर ने उल्लेख किया है, आप संचार के लिए एक बस का उपयोग कर सकते हैं।

बस का उपयोग करने के मामले में आपके पास कुछ विकल्प हैं:

ओटो घटना बस पुस्तकालय (RxJava के पक्ष में पदावनत)

http://square.github.io/otto/

ग्रीन रोबोट के EventBus

http://greenrobot.org/eventbus/

NYBus (RxBus, RxJava का उपयोग करके लागू किया गया। EventBus के समान।)

https://github.com/MindorksOpenSource/NYBus


0

LocalBroadcastManager के अलावा , इवेंट बस और मैसेंजर पहले से ही इस प्रश्न का उत्तर देते हैं, हम सेवा से संवाद करने के लिए लंबित इरादे का उपयोग कर सकते हैं ।

जैसा कि मेरे ब्लॉग पोस्ट में यहाँ बताया गया है

सेवा और गतिविधि के बीच संचार PendingIntent.For का उपयोग कर कि हम उपयोग कर सकते हैं किया जा सकता है createPendingResult () .createPendingResult () का एक नया PendingIntent ऑब्जेक्ट बनाता है जिसे आप onActivityResult (int) के अंदर अपनी गतिविधि पर वापस परिणाम डेटा भेजने और सेवा डेटा भेजने के लिए सौंप सकते हैं। int, Intent) callback.Since a PendingIntent Parcelable है, और इसलिए इसे एक Intent अतिरिक्त में रखा जा सकता है, आपकी गतिविधि इस PendingIntent को सेवा में पारित कर सकती है। सेवा, बदले में, PendingIntent को सूचित करने के लिए कॉल () विधि भेज सकती है। एक घटना के onActivityResult के माध्यम से गतिविधि।

गतिविधि

public class PendingIntentActivity extends AppCompatActivity
{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PendingIntent pendingResult = createPendingResult(
100, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), PendingIntentService.class);
intent.putExtra("pendingIntent", pendingResult);
startService(intent);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100 && resultCode==200) {
Toast.makeText(this,data.getStringExtra("name"),Toast.LENGTH_LONG).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
}

सर्विस

public class PendingIntentService extends Service {

    private static final String[] items= { "lorem", "ipsum", "dolor",
            "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi",
            "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam",
            "vel", "erat", "placerat", "ante", "porttitor", "sodales",
            "pellentesque", "augue", "purus" };
    private PendingIntent data;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        data = intent.getParcelableExtra("pendingIntent");

        new LoadWordsThread().start();
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    class LoadWordsThread extends Thread {
        @Override
        public void run() {
            for (String item : items) {
                if (!isInterrupted()) {

                    Intent result = new Intent();
                    result.putExtra("name", item);
                    try {
                        data.send(PendingIntentService.this,200,result);
                    } catch (PendingIntent.CanceledException e) {

                        e.printStackTrace();
                    }
                    SystemClock.sleep(400);

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