I have a service that needs to notify the main activity. I use LocalBroadcastManager
, and it works fine, but LocalBroadcastManager
has been deprecated.
This is my actual code in the service:
public void onTokenRefresh() {
/* build the intent */
Intent intent = new Intent(ACTION_TOKENREFRESHED);
intent.putExtra("token", "xxx");
/* send the data to registered receivers */
try{
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
} catch (Throwable e){
//no exception handling
}
}
In the main activity, I get informed of the notification like this :
context.registerReceiver(broadcastReceiver, intentFilter);
What can I use now to remove the deprecated warning? All examples I found regarding sending data from service to activity use LocalBroadcastManager. Can someone give me a workable model for migrating my existing code?
NOTE
In my example, The onTokenRefresh
is called from inside a background thread
. That is very important because it means I can simultaneously receive several onTokenRefresh, and I must forward all these tokens to the activity. Most of the offered solutions use live data but make a declaration like :
public static final MutableLiveData<String> tokenLiveData = new MutableLiveData<>();
Background Thread1:
tokenLiveData.postValue(Token1);
Background Thread2 (at same time):
tokenLiveData.postValue(Token2);
Will forward ALL tokens received simultaneously to the main activity that observes the tokenLiveData? Will the main activity always receive for sure token1 and token2?
Make a service
class and define a LiveData
to replace the LocalBroadcastManager
responsibility like so:
//This service sends an example token ten times to its observers
public class MyService extends Service {
//Define a LiveData to observe in activity
public static final MutableLiveData<String> tokenLiveData = new MutableLiveData<>();
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//You need a separate thread if you don not use IntentService
Thread thread1 = new Thread() {
public void run() {
for (int i = 0; i < 10; i++) {
//send random strings az an example token ten times.
//You can remove this loop and replace it with your logic
String token1 = UUID.randomUUID().toString();
new Handler(Looper.getMainLooper()).post(() -> sendTokenToObserver("Thread1: " + token1));
}
}
};
thread1.start();
Thread thread2 = new Thread() {
public void run() {
for (int i = 0; i < 10; i++) {
String token2 = UUID.randomUUID().toString();
new Handler(Looper.getMainLooper()).post(() -> sendTokenToObserver("Thread2: " + token2));
}
}
};
thread2.start();
return START_STICKY;
}
//Post token to observers
public void sendTokenToObserver(String token) {
tokenLiveData.setValue(token);
}
}
Then start the service
in the activity
and observe the LiveData
like below:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//You can observe the emitted token here and do what you want(Show in view or notification).
//I've just logged it to the console.
startService(new Intent(this,MyService.class));
MyService.tokenLiveData.observe(this, token -> Log.d("token", token));
}
}
You can also start
the service
from another activity
and observe it in the MainActivity
;