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

5

84

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.

Pemba answered 25/10, 2011 at 9:21 Comment(1)
It's because when onDestroy() is called no longer events will be listen by receiver.Mainmast
O
95

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.

Ology answered 25/10, 2011 at 9:48 Comment(8)
Are you suggesting that I register in onResume INSTEAD of onCreate or as well as? Is onResume always called when an activity is created?Pemba
You should register onResume yes, onResume() is always called on the activity being displayed (it is the last method called before your activity appeares (developer.android.com/reference/android/app/Activity.html) if you only register onCreate() and unregister onPause(), then the next time the activity is brought to the foreground, onCreate() will not be called again and then it will not register the receiver again. And yes I mean INSTEAD of, do not do it onCreate().Ology
@SnowyTracks: can you comment on why it's preferable to perform BroadcastReceiver registration calls in onResume/onPause rather than onStart/onStop? Looking over the developer guide for bound services, I found this. Towards the end of this section, one is advised to perform service binding/unbinding in onStart/onStop rather than onResume/onPause (for performance reasons). I wonder if this also applies to BroadcastReceivers? Thanks in advance.Slipstream
@jvmk Agreed, the Android doc says to do this in onStart and onStop, I think in 99% of cases, it makes little difference, there is only a difference in behaviour is dialog activities or either partial foreground activities are used. But I will update my answer to be in line with the Android docOlogy
@Ology do we really unregister in onStop instead onPause?Gone
You changed the first paragraph to recommend onStart/onStop, but the 2nd paragraph still argues in favor of onResume/onPause. This is confusing! You could update the 2nd paragraph to match the 1st, but I think it's better to revert: The docs' advice about service binding doesn't seem to apply to registering broadcast receivers. In fact the docs about BR's explicitly say you could do it in either onResume/onPause or in onStart/onStop.Factory
I see you edited the 2nd paragraph yesterday... thanks for making an effort at a more consistent answer. But it still doesn't explain why one should use onStart/onStop instead of or in combination with onResume/onPause, which was the OP's question. Instead, the 2nd paragraph's explanation is equally true of onResume/onPause as it is of onStart/onStop: once onPause is called, the activity is no longer in the foreground. So we're left without a "why" for your recommendation.Factory
I use onStop and onPause fairly interchangeable, as long as i am using the same matching method for activity coming into foreground. OnStop is not called when a user turns off the screen... with the activity in the foreground, so updates could still be filtered to the activity in this state?Ology
S
19

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()

Subscription answered 25/10, 2011 at 9:46 Comment(1)
what if we still need to update the content in activity even if activity is in background, because user may resume the app and updated data should be shown in that case?Chefoo
F
12

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?

Factory answered 13/6, 2017 at 16:12 Comment(2)
Thank you for your answer to my question but your answer is confusing and not strictly accurate You say If you register in onStart(), don't also register them in onPause(), because that would be redundant: onPause() is never called without onStart() being called first. is just illogical and confusing especially when the accepted answer is perfectly accurate.Pemba
@jamesc: Oops, I meant onResume rather than onPause. You're right, that is a bit confusing. Fixed now. As for the accepted answer, I've commented on it. I believe this answer adds significant and relevant information that the accepted one doesn't offer.Factory
C
6

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().

Conic answered 14/10, 2016 at 14:18 Comment(1)
I'm doing this too. Had problems with onStop() aswellHeadwind
A
1

You should register and unregister your broadcast in onResume() and onPause() methods.

if you register in onStart() and unregister it in onStop(). that time you will get following issue.

if your device screen is lock that time onStop() is called and if you unlock that time onStart() is never called. thats why you have register and unregister it in onResume() and onPause() methods.

Alissaalistair answered 4/4, 2019 at 8:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.