Send broadcast intent from service to Application

2019-03-01 17:47发布

问题:

Is it possible to send an intent from a service to an Application class? Not Activity?

I wouldn't know what activity would be running at a particular time, so I am adding a boolean flag in the activity class that detects the activity and sends the appropriate data based on the broadcast received.

回答1:

If your Service is active, then your Application class is active as well.

Otherwise you wouldn't be able to use getApplicationContext().

Although I'm skeptic about a service that runs forever there is a very clean way to make the Service communicate with a certain Activity, should the last one be currently active.

Such clean way is called LocalBroadcastManager.

The Activity meant to receive the data should register a BroadcastReceiver in onResume() and unregister it in onPause().

You instantiate your BroadcastReceiver in your Activity's onCreate()

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.
    }
}

You create a Filter so your Activity only listens to a certain type of signals.

private IntentFilter notifIntentFilter new IntentFilter("com.you.yourapp.MY_SIGNAL");

in onResume()

LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(this.localBroadcastReceiver, notifIntentFilter);

in onPause()

LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);

Now whenever you want to send data to your Activity, your Service can call:

final Intent intent = new Intent();
intent.setAction("com.you.yourapp.MY_SIGNAL");
// put your data in intent

LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

If your Activity is awake, it will respond to the signal. Otherwise, if it's in the background, or it is not instantiated it won't.

You can apply this pattern to as many Activities as you wish.


Still, I have never used this inside the Application class. But you can try to register your receiver there. It might work, since if the Application class is destroyed, the BroadcastReceiver is destroyed too and thus probably unregistered as well.

The point is, if your Application gets destroyed, your Service will be killed as well. Unless you launched it in another process. But then it will have it's own instance of Application; and this is a complex thing you probably do not want to get into details now...


Important: since the Application class is not tied to any UI component, you can do whatever you need directly inside your service. If you need to manipulate the UI, then the pattern described above will work for you.

Please read about new Android's background limitations.


Edit:

Oh yeah right, if you need your Service to call a function declared in your Application class, you can just do

((MyApplication) getApplication()).myFunctionToHandleData(Intent intent);

I didn't really understand your question though, but either of the methods described above should work for you.