How to have Android Service communicate with Activity
Asked Answered
F

13

274

I'm writing my first Android application and trying to get my head around communication between services and activities. I have a Service that will run in the background and do some gps and time based logging. I will have an Activity that will be used to start and stop the Service.

So first, I need to be able to figure out if the Service is running when the Activity is started. There are some other questions here about that, so I think I can figure that out (but feel free to offer advice).

My real problem: if the Activity is running and the Service is started, I need a way for the Service to send messages to the Activity. Simple Strings and integers at this point - status messages mostly. The messages will not happen regularly, so I don't think polling the service is a good way to go if there is another way. I only want this communication when the Activity has been started by the user - I don't want to start the Activity from the Service. In other words, if you start the Activity and the Service is running, you will see some status messages in the Activity UI when something interesting happens. If you don't start the Activity, you will not see these messages (they're not that interesting).

It seems like I should be able to determine if the Service is running, and if so, add the Activity as a listener. Then remove the Activity as a listener when the Activity pauses or stops. Is that actually possible? The only way I can figure out to do it is to have the Activity implement Parcelable and build an AIDL file so I can pass it through the Service's remote interface. That seems like overkill though, and I have no idea how the Activity should implement writeToParcel() / readFromParcel().

Is there an easier or better way? Thanks for any help.

EDIT:

For anyone who's interested in this later on, there is sample code from Google for handling this via AIDL in the samples directory: /apis/app/RemoteService.java

Foreglimpse answered 17/3, 2010 at 14:46 Comment(0)
J
103

There are three obvious ways to communicate with services:

  1. Using Intents
  2. Using AIDL
  3. Using the service object itself (as singleton)

In your case, I'd go with option 3. Make a static reference to the service it self and populate it in onCreate():

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

Make a static function MyService getInstance(), which returns the static sInstance.

Then in Activity.onCreate() you start the service, asynchronously wait until the service is actually started (you could have your service notify your app it's ready by sending an intent to the activity.) and get its instance. When you have the instance, register your service listener object to you service and you are set. NOTE: when editing Views inside the Activity you should modify them in the UI thread, the service will probably run its own Thread, so you need to call Activity.runOnUiThread().

The last thing you need to do is to remove the reference to you listener object in Activity.onPause(), otherwise an instance of your activity context will leak, not good.

NOTE: This method is only useful when your application/Activity/task is the only process that will access your service. If this is not the case you have to use option 1. or 2.

Jea answered 17/3, 2010 at 15:54 Comment(8)
How can I busy-wait the Activity? Can you explain please ?Hostelry
So either after onCreate or after onStartCommand in your service class set a public static variable, call it isConnected or something to true. Then in your Activity do this: Intent intent = new Intent(act, YourService.class); startService(intent); while(!YourService.isConnected) { sleep(300); } After that loop your service is running and you can do communication with it.. In my experience there are definitely some limitations to interacting with a service like this.Rosenwald
Why it can be started only in Activity.onCreate()?Kyliekylila
Any word on why you wouldn't want to use Intents by sending data through Parcellable messages between them?Broomcorn
This works, but @MaximumGoat's answer is much cleaner and doesn't involve any busy-waiting.Neuroticism
this "busy-waiting" thing with sleep(xxx) I don't like at all.. Looks like not so good design pattern..Judijudicable
@DanHulme You are correct, I changed my reply so that the service notifies the calling activity when it's ready.Jea
I used a broadcastReciever inform the calling activity when the service is readyFoliole
D
283

The asker has probably long since moved past this, but in case someone else searches for this...

There's another way to handle this, which I think might be the simplest.

Add a BroadcastReceiver to your activity. Register it to receive some custom intent in onResume and unregister it in onPause. Then send out that intent from your service when you want to send out your status updates or what have you.

Make sure you wouldn't be unhappy if some other app listened for your Intent (could anyone do anything malicious?), but beyond that, you should be alright.

Code sample was requested:

In my service, I have this:

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

(RefreshTask.REFRESH_DATA_INTENT is just a constant string.)

In my listening activity, I define my 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
        }
    }
}

I declare my receiver at the top of the class:

private DataUpdateReceiver dataUpdateReceiver;

I override onResume to add this:

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

And I override onPause to add:

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

Now my activity is listening for my service to say "Hey, go update yourself." I could pass data in the Intent instead of updating database tables and then going back to find the changes within my activity, but since I want the changes to persist anyway, it makes sense to pass the data via DB.

Diphthong answered 19/1, 2011 at 19:45 Comment(11)
How? What you describe is exactly what I need. But more than that, I need complete sample code. Thanks in advance. FYI, the last time I tried to write a widget, the messaging part took me 2 months. Laugh if you want, but you experts need to publish more since IMHO Android is more complicated than iOS !Petra
aaaaaaa, The Busy Coder's Guide to Advanced Android Development has an excellent chapter on widgets. It's the only resource that got me through that mess. CommonsWare, the author, has 115k reputation on StackOverflow, and I highly recommend the book. commonsware.com/AdvAndroidDiphthong
Broadcasts are fantastic and in addition if you dont want your broadcast to go beyond your own process then consider using a LocalBroadcast: developer.android.com/reference/android/support/v4/content/…Tutor
is this recommended way to send a lot of data from service to activity? I mean putting extra in intent and broadcasting it from service, registering broadcast reciever in activity? 10qJudijudicable
This is very good way of communication. But what to do in case results were delivered, when activity was in paused state? So after onResume activity can wait a long time for results. And no data will be received, because data were missed.Raphaelraphaela
Anton M.: Your activity could query the database in onResume as well as when it receives notice that the data has been updated.Diphthong
If you don't unregister your receiver in onPause, your app can receive broadcasts in the background w/o waking up, and act on them with a Notification to the user for example.Fumed
@CodyCaughlan I see the method sendBroadcast returns a boolean value and I don't know what that means?Garner
Why do we set the listener in the onResume() instead of in the onCreate()Mehitable
LocalBroadcastManager is now deprecated in favour of LiveData or other observer pattern tools: developer.android.com/reference/androidx/localbroadcastmanager/…Teledu
Please update the answer to mention/prefer LocalBroadcastBoulder
J
103

There are three obvious ways to communicate with services:

  1. Using Intents
  2. Using AIDL
  3. Using the service object itself (as singleton)

In your case, I'd go with option 3. Make a static reference to the service it self and populate it in onCreate():

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

Make a static function MyService getInstance(), which returns the static sInstance.

Then in Activity.onCreate() you start the service, asynchronously wait until the service is actually started (you could have your service notify your app it's ready by sending an intent to the activity.) and get its instance. When you have the instance, register your service listener object to you service and you are set. NOTE: when editing Views inside the Activity you should modify them in the UI thread, the service will probably run its own Thread, so you need to call Activity.runOnUiThread().

The last thing you need to do is to remove the reference to you listener object in Activity.onPause(), otherwise an instance of your activity context will leak, not good.

NOTE: This method is only useful when your application/Activity/task is the only process that will access your service. If this is not the case you have to use option 1. or 2.

Jea answered 17/3, 2010 at 15:54 Comment(8)
How can I busy-wait the Activity? Can you explain please ?Hostelry
So either after onCreate or after onStartCommand in your service class set a public static variable, call it isConnected or something to true. Then in your Activity do this: Intent intent = new Intent(act, YourService.class); startService(intent); while(!YourService.isConnected) { sleep(300); } After that loop your service is running and you can do communication with it.. In my experience there are definitely some limitations to interacting with a service like this.Rosenwald
Why it can be started only in Activity.onCreate()?Kyliekylila
Any word on why you wouldn't want to use Intents by sending data through Parcellable messages between them?Broomcorn
This works, but @MaximumGoat's answer is much cleaner and doesn't involve any busy-waiting.Neuroticism
this "busy-waiting" thing with sleep(xxx) I don't like at all.. Looks like not so good design pattern..Judijudicable
@DanHulme You are correct, I changed my reply so that the service notifies the calling activity when it's ready.Jea
I used a broadcastReciever inform the calling activity when the service is readyFoliole
W
41

Use LocalBroadcastManager to register a receiver to listen for a broadcast sent from local service inside your app, reference goes here:

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

Wamble answered 13/1, 2012 at 2:15 Comment(2)
Yes, a very nice discussion about localbroadcast here linkHull
LocalBroadcastManager is now deprecated in favour of LiveData or other observer pattern tools: developer.android.com/reference/androidx/localbroadcastmanager/…Teledu
O
27

You may also use LiveData that works like an EventBus.

class MyService : LifecycleService() {
    companion object {
        val BUS = MutableLiveData<Any>()
    }

    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
    }
}

Then add an observer from your Activity.

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

You can read more from this blog.

Oraorabel answered 19/11, 2018 at 7:1 Comment(1)
Dig this approach.Baudelaire
C
22

Using a Messenger is another simple way to communicate between a Service and an Activity.

In the Activity, create a Handler with a corresponding Messenger. This will handle messages from your Service.

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());

The Messenger can be passed to the service by attaching it to a Message:

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

A full example can be found in the API demos: MessengerService and MessengerServiceActivity. Refer to the full example for how MyService works.

Chur answered 25/2, 2012 at 21:16 Comment(1)
Much appreciated! Works perfectly. Just a detail in the code: myService.send(message); should be messenger.send(message); instead.Varicella
A
21

I am surprised that no one has given reference to Otto event Bus library

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

I have been using this in my android apps and it works seamlessly.

Adjacent answered 11/3, 2014 at 11:22 Comment(2)
Alternatively, there is greenrobot's EventBus library.Occidental
But remember that EventBus and otto are always in one process. When you are using a service that is in its own process (started with setting the android:process=":my_service" they are not able to communicate.Progressionist
I
10

The other method that's not mentioned in the other comments is to bind to the service from the activity using bindService() and get an instance of the service in the ServiceConnection callback. As described here http://developer.android.com/guide/components/bound-services.html

Inca answered 4/12, 2014 at 20:35 Comment(2)
This is the right way of getting reference of service instance.Francoise
This will generally work, except in instances where one is extending MediaBrowserServiceCompat service. If we don't allow it to handle binding and we use our own binder, then onGetRoot will never get called, meaning Android Auto and Android Automotive OS simply won't work, because they won't be able to get the content hierarchy.Baudelaire
H
9

Binding is another way to communicate

Create a callback

public interface MyCallBack{

   public void getResult(String result);

}

Activity side:

  1. Implement the interface in the Activity

  2. Provide the implementation for the method

  3. Bind the Activity to Service

  4. Register and Unregister Callback when the Service gets bound and unbound with Activity.

    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 );
          }
    
     }
    

Service Side:

  1. Initialize callback

  2. Invoke the callback method whenever needed

     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;
        }
     }
    
Hernadez answered 9/5, 2019 at 5:56 Comment(3)
your serviceConnection is out of onCreate. Please edit it.Norvol
It does not have to be inside onCreateHernadez
If anyone tries to copy this into a file and convert it to Kotlin, Android Studio doesn't prepend inner to the GPSBinder class and it throws a compiler error. Make sure to add inner in front of the nested class and it will work fine.Sextan
S
2

Another way could be using observers with a fake model class through the activity and the service itself, implementing an MVC pattern variation. I don't know if it's the best way to accomplish this, but it's the way that worked for me. If you need some example ask for it and i'll post something.

Sices answered 26/3, 2012 at 13:58 Comment(1)
I'm struggling with similar think. I have activity and 2 services that have the same Model. The model can be updated in either activity or any those service so I thought about using Observers somehow but cant figure it out. Can you post example to show your idea?Tivoli
I
2

To follow up on @MrSnowflake answer with a code example. This is the XABBER now open source Application class. The Application class is centralising and coordinating Listeners and ManagerInterfaces and more. Managers of all sorts are dynamically loaded. Activity´s started in the Xabber will report in what type of Listener they are. And when a Service start it report in to the Application class as started. Now to send a message to an Activity all you have to do is make your Activity become a listener of what type you need. In the OnStart() OnPause() register/unreg. The Service can ask the Application class for just that listener it need to speak to and if it's there then the Activity is ready to receive.

Going through the Application class you'll see there's a loot more going on then this.

Illegal answered 17/8, 2013 at 18:41 Comment(2)
The provided link now results in a github 404. Did it move?Floris
Yep, seems to work now. Must have been a temporary issue on github.Floris
A
2

Besides LocalBroadcastManager , Event Bus and Messenger already answered in this question,we can use Pending Intent to communicate from service.

As mentioned here in my blog post

Communication between service and Activity can be done using PendingIntent.For that we can use createPendingResult().createPendingResult() creates a new PendingIntent object which you can hand to service to use and to send result data back to your activity inside onActivityResult(int, int, Intent) callback.Since a PendingIntent is Parcelable , and can therefore be put into an Intent extra,your activity can pass this PendingIntent to the service.The service, in turn, can call send() method on the PendingIntent to notify the activity via onActivityResult of an event.

Activity

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);
}
}

Service

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);

                }
            }
        }
    }
}
Aglaia answered 27/3, 2018 at 9:8 Comment(0)
M
2

My method:

Class to manage send and receive message from/to service/activity:

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 **/

}

In Activity Example:

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 **/

In Service Example:

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 */

Send a message from Activity / Service:

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

How this works:

on the activity you start or bind the service. The service "OnBind" methods return the Binder to his MessageManager, the in the Activity through the "Service Connection" interface methods implementation "OnServiceConnected" you get this IBinder and init you MessageManager using it. After the Activity has init his MessageManager the MessageHandler send and Handshake to the service so it can set his "MessageHandler" sender ( the "private Messenger mMsgSender;" in MessageManager ). Doing this the service know to who send his messages.

You can also implement this using a List/Queue of Messenger "sender" in the MessageManager so you can send multiple messages to different Activities/Services or you can use a List/Queue of Messenger "receiver" in the MessageManager so you can receive multiple message from different Activities/Services.

In the "MessageManager" instance you have a list of all messages received.

As you can see the connection between "Activity's Messenger" and "Service Messenger" using this "MessageManager" instance is automatic, it is done through the "OnServiceConnected" method and through the use of the "Handshake".

Hope this is helpful for you :) Thank you very much! Bye :D

Mcgrew answered 1/2, 2019 at 13:26 Comment(0)
U
0

As mentioned by Madhur, you can use a bus for communication.

In case of using a Bus you have some options:

Otto event Bus library (deprecated in favor of RxJava)

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

Green Robot’s EventBus

http://greenrobot.org/eventbus/

NYBus (RxBus, implemented using RxJava. very similar to the EventBus)

https://github.com/MindorksOpenSource/NYBus

Ungraceful answered 7/2, 2018 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.