When to unregister BroadcastReceiver? In onPause()

2019-01-22 17:59发布

问题:

When should I use unregisterReceiver? In onPause(), onDestroy(), or onStop()?

Note: I need the service to run in the background.

Update:

  1. I get an exception releasing receivers null.

  2. Activity has leaked intent receivers are you missing call to unregisterReceiver();

Please tell me if there's something wrong, here's my code:

private boolean processedObstacleReceiverStarted;
private boolean mainNotificationReceiverStarted;

protected void onResume() {

    super.onResume();
    try {
        registerReceivers();

    } catch (Exception e) {

        Log.e(MatabbatManager.TAG,
                "MAINActivity: could not register receiver for Matanbbat Action "
                        + e.getMessage());
    }
}

private void registerReceivers() {

    if (!mainNotificationReceiverStarted) {
        mainNotificationReceiver = new MainNotificationReceiver();

        IntentFilter notificationIntent = new IntentFilter();

        notificationIntent
                .addAction(MatabbatManager.MATABAT_LOCATION_ACTION);
        notificationIntent
                .addAction(MatabbatManager.MATABAT_New_DATA_RECEIVED);
        notificationIntent
                .addAction(MatabbatManager.STATUS_NOTIFCATION_ACTION);
        registerReceiver(mainNotificationReceiver, notificationIntent);

        mainNotificationReceiverStarted = true;

    }

    if (!processedObstacleReceiverStarted) {
        processedObstacleReceiver = new ProcessedObstacleReceiver();
        registerReceiver(processedObstacleReceiver, new IntentFilter(
                MatabbatManager.MATABAT_ALARM_LOCATION_ACTION));
        processedObstacleReceiverStarted = true;

    }

}

private void unRegisterReceivers() {

    if (mainNotificationReceiverStarted) {
        unregisterReceiver(mainNotificationReceiver);
        mainNotificationReceiverStarted = false;
    }
    if (processedObstacleReceiverStarted) {
        unregisterReceiver(processedObstacleReceiver);
        processedObstacleReceiverStarted = false;
    }

}


@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

    try {

        unRegisterReceivers();
        mWakeLock.release();//keep screen on
    } catch (Exception e) {
        Log.e(MatabbatManager.TAG, getClass() + " Releasing receivers-" + e.getMessage());
    }

}

回答1:

it depends on where you have register the receiver. The complementary method pairs are

onCreate - onDestroy
onResume - onPause
onStart  - onStop

if you register the receiver in the first one then unregister it in it's ending method.



回答2:

From the Android documentation:

You should implement onStop() to release activity resources such as a network connection or to unregister broadcast receivers.

Then, I would follow these pairs (using @StinePike's analogy):

onResume - onPause
onStart  - onStop

Because of the Android Lifecycle, and as @w3bshark mentioned:

In post-HoneyComb (3.0+) devices, onStop() is the last guaranteed handler.



回答3:

An broadcast receiver is an invisible component. All it does it respond to some kind of an change via onReceive() callback.

So it makes sense to activate them , only when your activity is in a state to respond or when it is becoming Enabled /active - which is when onResume() is called.

So it is a better practice to register in onResume() - When activity is visible & Enabled and unregister in onStop() when activity is no longer Active.



回答4:

It is just as simple as that, if you want to listen for events even when your activity is not visible then call unregister in onStop() (E.g From Activity A you open Activity B but if you want A to still listening for the events).

But when you only want to listen only for events when your activity is visible then in onPause call unregister() (E.g From Activity A you opened Activity B but now you do not want to listen for events in activity A).

Hope this helps your problem.