When to Register/Unregister Broadcast Receivers created in an activity?

I have a need to create a custom broadcast receiver in the onCreate event of an activity and obviously I need to unRegister the broadcast receiver in the onDestroy event of the activity

For clarity this is a snippet of the code I use

public class AnActivity extends Activity {
    private ResponseReceiver receiver;

    public class ResponseReceiver extends BroadcastReceiver {
           public static final String ACTION_RESP =
              "mypackagename.intent.action.MESSAGE_PROCESSED";

           @Override
            public void onReceive(Context context, Intent intent) {
// TODO Start a dialogue if message indicates successfully posted to server
            }
    }   

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new ResponseReceiver();
        registerReceiver(receiver, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

I have read that onPause/onResume and onStart/onStop events for the activity should also register and unregister the broadcast receiver.

I'm really wanting to understand what is considered to be the best practice for this and why.


Solution 1:

You should register and unregister your receivers onStart() and onStop().

The only reason an Activity would register BroadcastReceivers is to use the events in some way on the current activity, to inform the User of an event. If onStop() has been called, then the Activity is no longer in the foreground, and therefore cant update the User.

If you want to receive broadcast events in the background you should consider using a service as indicated here.

Like Konstantin says, onDestroy() is not guaranteed to be called, and you could continue receiving broadcasts for a long time, when the Activity is no longer open.

Solution 2:

As onDestroy() is not guaranted to be called you shall use onPause() to deregister. Consider lifecycle of your broadcast receiver: Do you need it to be active, only when your activity is in foreground? Then use onResume() / onPause()

Solution 3:

The Android documentation doesn't prescribe a single place to register/unregister broadcast receivers, but it mentions both onStart()/onStop() and onResume()/onPause() as possibilities.

The biggest factor in making this decision is, when does your receiver need to be able to do its job? This will determine when to register and unregister it.

  • Does the receiver need to do something about the broadcast only when the activity is in focus? If so, you can register/unregister it in onPause()/onReceive(). (You can also use a longer lifetime such as onStart()/onStop(), but then you should check during the receiver's onReceive() whether the activity is in focus.)

  • Does the receiver need to do something when visible, even if it doesn't have focus (e.g. when a dialog is being shown)? If so, use onStart()/onStop() (or a longer lifetime, but again, the receiver's onReceive() should check whether the activity is visible).

  • Does the receiver need to know about the broadcast even when the activity isn't visible? For example, does it need to remember that something has happened, so that when the activity becomes visible, it can reflect the resulting state of affairs? Then you need to use onCreate()/onDestroy() to register/unregister. (Note there are other ways to implement this kind of functionality.)

If you register in onStart(), don't also register them in onResume(), because that would be redundant: onResume() is never called without onStart() being called first.

Also keep in mind that it's best to keep onPause() as light as possible:

onPause() execution is very brief, and does not necessarily afford enough time to perform save operations. For this reason, you should not use onPause() to save application or user data, make network calls, or execute database transactions; such work may not complete before the method completes. Instead, you should perform heavy-load shutdown operations during onStop().

It's true that onDestroy() is not guaranteed to be called if the system kills your process in order to save memory. However if the process is killed, the process won't be receiving broadcasts anyway. In that case, is it really necessary to unregister broadcast receivers?

Solution 4:

Android can kill your application with omitting onStop() method. The best way to solve that situation is register BroadcastReceiver in onResume() method and unregister in onPause().