3

I have a service and an Activity (both running as a part of the same process). As per the SO answer, https://stackoverflow.com/a/29101448/1215996. It is suggesting to pass an Activity reference to the Service so the service can call the callbacks on the Activity object.

1) Is it a good idea to communicate this way. Won't it be bad, since it is leaking a reference to the Activity which will avoid GC until Service holds its reference.

2) I have also checked that Messenger can be used for to and fro communication b/w Activity and Service. AFAIK, this is meant to be used if Activity and Service runs in different processes. Using this mechanism won't be an overhead for communication b/w Activity and Service when they run as part of the same process?

What is the best way to communicate? My main aim is to provide some message from the Service to the Activity when some event occurs in the service.

Community
  • 1
  • 1
Sumit Trehan
  • 3,985
  • 3
  • 27
  • 42
  • 1
    if you have local service use "local bound service" pattern (the same pattern that is used in SO answer you posted) – pskink Feb 07 '16 at 13:26
  • I am calling bindService() method to bind to the service and i am able to call service class methods. However the problem is the reverse communication, that is what my question is about. I want the service to notify the Fragment/Activity for certain events. – Sumit Trehan Feb 07 '16 at 13:42
  • what is the problem with the reverse communication? just use `register()` / `unregister()` methods either using a simple `List` of clients or trying `android.os.RemoteCallbackList` – pskink Feb 07 '16 at 13:53
  • during register(), should I pass activity/fragment? If yes, then my 1st point in question is about that. – Sumit Trehan Feb 07 '16 at 13:54
  • as i said, use `register()` / `unregister()` methods, call `unregister()` when your client is finished – pskink Feb 07 '16 at 13:55
  • Ok... So you are saying using this means of communication is good enough (from the programming practice point of view) – Sumit Trehan Feb 07 '16 at 13:58
  • you are asking what is wrong in "local bound service" pattern? this is the optimal pattern if you have local services, so use it – pskink Feb 07 '16 at 14:03

1 Answers1

12

Never pass an Activity reference to anything that could live longer than the Activity. Ever. Don't leak Activity references.

There is no "best way" to communicate between an Activity and a Service, but there are lots of options and you can choose the one that's best for your use case.

An Activity typically communicates with a "started Service" by sending it an Intent with startService. This is usually preferred over a "bound Service" because it's less code and more straightforward. Starting a service this way basically packages up some data for the Service to deal with on its own. You can think of startService as saying, "Hey, service, do this work for me". And since an Intent can't contain "leakable" object references, it's safe in that respect.

For a Service to communicate back to an Activity:

LocalBroadcastManager

This works like the regular Android broadcast mechanism, except the broadcasts never leave your application (so they can't be intercepted by other apps).

Event Bus

Google doesn't provide an official event bus, but there lots out there to choose from if you simply search for "Android event bus". These provide features that make them easier to use than LocalBroadcastManager and also allow some sense of state for various data broadcasts that you define. Which one you choose may depend on the features provided or the style of expression you prefer.

Bound Service

This is similar to Messenger, but sets up a formal "link" between the client and the Service. You can use it to perform RPC style calls between the same or different processes (with a Messenger). Bear in mind that each time an activity comes and goes (like an orientation change) it has to unbind and rebind to the service. This interruption may not be good for your activity logic.

There might be other options, but these are the ones used most often that I know of.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441