What is the preferred way to call an Android Activity back from a Service thread What is the preferred way to call an Android Activity back from a Service thread multithreading multithreading

What is the preferred way to call an Android Activity back from a Service thread


I prefer using LocalBroadcastManager

Here's an example for the code in your Activity:

BroadcastReceiver localBroadcastReceiver = new BroadcastReceiver(){    @Override    public void onReceive(Context context, Intent intent)    {        Log.d("BroadcastReceiver", "Message received " + intent.getAction());        Log.d("BroadcaseReceiver", "Received data " + intent.getStringExtra("com.my.package.intent.EXTRA_DATA"));    }};@Overrideprotected void onStart(){    super.onStart();    final LocalBroadcastManager localBroadcastManager =        LocalBroadcastManager.getInstance(this);    final IntentFilter localFilter = new IntentFilter();    localFilter.addAction("com.my.package.intent.ACTION_NAME_HERE");    localBroadcastManager.registerReceiver(localBroadcastReceiver, localFilter);}@Overrideprotected void onStop(){    super.onStop();    final LocalBroadcastManager localBroadcastManager =        LocalBroadcastManager.getInstance(this);    // Make sure to unregister!!    localBroadcastManager.unregisterReceiver(localBroadcastReceiver);}

Anywhere else in your codebase (such as in the completion of your background thread):

final LocalBroadcastManager localBroadcastManager =    LocalBroadcastManager.getInstance(context);final Intent intent = new Intent("com.my.package.intent.ACTION_NAME_HERE")intent.putExtra("com.my.package.intent.EXTRA_DATA", yourBackgroundData);localBroadcastManager.sendBroadcast(intent);

You can, of course, use intent.putExtra to add any additional data or use multiple actions to differentiate broadcast messages.


We've done this by centralizing all communication between activities and service in the Application class. We extend the Application class and then have methods there that bind to the service and accept the callbacks. There is no direct connection between an Activity and the Service in this architecture.

The advantage of this mechanism is that you don't have to worry about unbinding/rebinding to the service during activity transitions and activity death and recreations. The Application class manages all this and it isn't affected by what activities do. The Application class receives all the callbacks, and you will need to have code there to determine what to do with the callbacks. Probably you will want to store some data in the Application class and then notify the activities that there is new data available, or something similar.

Another approach is to have the Service broadcast the callbacks. In this case the coupling between the service and the activities is loose, so you wouldn't need to create a Handler in the activity and then pass it to the Service. Activities can just register BroadcastReceivers for the callbacks they are interested in, or you can manage this in the manifest.


One solution, as you say, is to use MyActivity.handleMessage(Message). Whenever your activity starts (or is restarted) you will probably attempt to start the service (the "onBind" stuff you mention). If the service is already running, no harm is done. Once the bind stuff is done you tell the service the Messenger to send replies to.

To ensure restarts are handled, in onStop you need to tell the service to remove that Messenger from it's "list of places to send replies to" so that it doesn't accidentally send a message to a now non-existent Messenger. When onStart is called as part of the restart, it will send the now-correct Messenger.

Obviously this requires that the service handle this and somehow manage the scenario in which it has a response to send while there is no Messenger to send it to. Either it holds to information until such time as a Messenger is available or it drops the information, and the Activity gets all the state information explicitly as a follow on to the bind stuff it has done in onStart.

Another approach is to have the Activity poll the Service every so often (10 seconds?) when it knows that there is processing going on to see if the results are available, and then to stop polling once all the information is back.