What is the best way to communicate between a service and an activity?

Activity can now connect to services using one of three methods:

I think BroadcastReceivers is the easiest way to communicate, but I wonder why and when to use other methods? or, in other words, in which cases will racers or AIDL be better used than broadcast translators?

+7
android
source share
4 answers

You can use BroadcastReceiver if you need a connection between Service and Activity in your application.

Messenger and AIDL are mainly used when your application needs to interact with other processes ( IPC ). In this case, your interface should have a Service that defines a Handler that responds to different types of Message objects.

Now the difference between Messenger and AIDL pretty simple. When you use Messenger , it puts all requests in a single thread. Therefore, your Service does not have to be thread safe. If you want your Service process multiple requests at once, you can directly use AIDL . In this case, your Service should be able to multithread and be thread safe. In fact, Messenger is implemented at the top of AIDL .

For a better understanding, see Related Services.

You should also check BroadcastReceiver or Messenger response through handler

+8
source share

I mainly use LocalBroadcasts . They are essentially similar to real broadcasts, but only visible to your application. First you need to create a BroadcastReceiver like you, with a normal broadcast:

 private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(Intent.SOME_ACTION.equals(action)) { // Do your work } } }; 

You can then register and unregister BroadcastReceiver as follows:

 @Override public void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(Intent.SOME_ACTION); LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity()); manager.registerReceiver(broadcastReceiver, intentFilter); } @Override public void onPause() { super.onPause(); LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity()); manager.unregisterReceiver(broadcastReceiver); } 

And finally, you can send the broadcast from your Service or anywhere else in your application as follows:

 Intent intent = new Intent(Intent.SOME_ACTION); LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity()); manager.sendBroadcast(intent); 
+10
source share

Xaver Kapeller's answer is really good. However, it has a (main) drawback: the transmission may be skipped.

When a user switches from Activity (for example, showing the latest applications), you will unregister your BroadcastReceiver s. If a broadcast is sent at this point, your Activity will not receive it. When you re-move to Activity it may be in an invalid state.


Using ResultReceiver , you still get the result in this case. In addition, ResultReceiver is parcelable , so you can save and restore it in life cycle events.
This causes some overhead, so I created this experimental library to make it a little easier. So far, it only uses IntentService s, but it should be easy enough to extend it.

+3
source share

If your service is used only by the local application and you do not need to work through processes, you can implement your own Binder class , which gives your client direct access to public methods in the service .

Note. This only works if the client and the service are in the same application and process, which is most common.

Binder class extension http://developer.android.com/guide/components/bound-services.html#Binder

+2
source share

All Articles