If you want to implement a communication pattern between a Service
and an Activity
, you should use a LocalBroadcastManager.
It will turn handy because, in case your Service
is still on but your Activity
has been destroyed (very common situation), then the 'messagging' between the two will simply have no effect (no NPE
or whatsoever will be thrown).
Step 1
Create a BroadcastReceiver
in your Activity
and define an ID
/ Filter
this.localBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Do what you have to do here if you receive data from the Service / Background Task
}
}
public static final IntentFilter SIGNAL_FILTER = new IntentFilter("com.you.yourapp.MY_SIGNAL")
Step 2
In your Activity
register the broadcast in onResume()
and unregister it in onPause()
.
@Override
protected void onResume() {
// Listen if a Service send me some data
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(this.localBroadcastReceiver, SIGNAL_FILTER);
}
@Override
protected void onPause() {
// I'm going to the background / or being destroyed: no need to listen to anything anymore...
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);
}
Your Activity
is now ready to receive data from any other component in your Application
.
If it's in the background, then there is no need to update the UI
: in fact the Activity
will not respond if in the background.
In the same way, if it's being garbage collected, the Receiver
will be unregistered and the Activity
will just not respond to anything.
If the Activity
is resumed / restarted, onResume()
will be triggered and the Receiver
will be registered again.
Step 3
All you need to do right now, is send data from the Service
.
Simply call
final Intent intent = new Intent();
intent.setAction(SomeActivity.SIGNAL_FILTER);
// put your data in intent
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
and your Activity
will accordingly respond to the signal.
It's surprising how few people know about the LocalBroadcastManager
and instead use some self-implemented callback / singleton pattern, which increases complexity and non-readability.
This pattern is built-in in Android
, so you don't need external libraries. As for security, this ensures that your signals stay internal to your application: no data can therefore be read by other apps.
I similarly answered to another question here.