I had to implement a feature to this app which consists of an Activity
and a Service
working on the background (it implements Service
, not IntentService
).
I went through a few tutorials on the Internet that are supposed to work, and they all use LocalBroadcastManager
, which by the way is the recommended by Android:
If you don't need to send broadcasts across applications, consider using this class with
LocalBroadcastManager
instead of the more general facilities described below.
I literally lost a day to find out the problem why it wouldn't work for me: it only works if I use Context.sendBroadcast()
. and Context.registerReceiver()
instead of the LocalBroadcastManager
methods.
Now my app is working, but I feel I am going against the best practices, and I don't know why. Any ideas why it could be happening?
EDIT:
After I wrote this question I went further on the problem. LocalBroadcastManager
works through a Singleton, as we should call LocalBroadcastManager.getInstance(this).method()
. I logged both instances (in the Activity
and in the Service
) and they have different memory addresses.
Now I came to another question, shouldn't a Service
have the same Context
as the Activity
that called it? From this article a Service runs on the Main Thread, hence I'd think the Context
would be
the same.
Any thoughts on that? (sorry for the long post)
Code samples:
MyService
public class MyService extends Service {
...
// When an event is triggered, sends a broadcast
Intent myIntent = new Intent(MainActivity.MY_INTENT);
myIntent.putExtra("myMsg","msg");
sendBroadcast(myIntent);
// Previously I was trying:
// LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(myIntent);
}
MyActivity
public class MainActivity {
...
private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive", "received!");
// TODO something
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(messageReceiver, new IntentFilter(MY_INTENT));
// Previously I was trying:
// LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(messageReceiver, new IntentFilter(MY_INTENT));
}
}
I've never used LocalBroadcastManager, but it sounds like you have to register your receiver on there (i.e. lbm.registerReceiver(...)
, not mycontext.registerReceiver(...)
). Are you doing that?
Now I came to another question, shouldn't a Service have the same Context as the Activity that called it? From this article a Service runs on the Main Thread, hence I'd think the Context would be the same.
The Context class is not related to threads. In fact, both Service and Activity are (indirect) subclasses of Context -- so they're their own Contexts!
That's why you can use "this" as a Context.
But regardless of which context you send into LocalBroadcastManager.getInstance()
, you should be getting the exact same LBM instance out. I can't think of any reason that you wouldn't -- except if you're running the Activity and Service in different processes?