1

Im using local BroadcastReceivers in some of my activities to handle broadcasts sent through LocalBroadcastManager. I saw many recommendations (e.g. here) that suggest not to register/unregister those receivers in onCreate/onDestroy activity handlers.

I dont quite understand why. The "official" explanation is that onDestory is not guaranteed to be called everytime the activity is destroyed :

"There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it..."

Doesn't "killing the hosting process" means that there is an overall cleanup of the entire activities' resources ? Doesnt this cleanup include locally registered receivers ? How come this recommendation doesnt apply to other locally defined objects ? How come they are guaranteed to be cleaned and BroadcastReceivers not ?

Appreciate your knowledgable advices.

Community
  • 1
  • 1
AsafK
  • 2,425
  • 3
  • 32
  • 38

2 Answers2

2

I don't quite understand why.

Common uses of a LocalBroadcastManager in an activity only need to receive broadcasts when the activity is in the foreground. Hence, onResume()/onPause() are the proper choice for those scenarios.

If you feel that registering/unregistering in onCreate()/onDestroy() is what you want to do, and doing so does not harm the user (e.g., waste CPU time processing irrelevant events), you are welcome to do so.

Doesn't "killing the hosting process" means that there is an overall cleanup of the entire activities' resources ?

Yes, it does.

Doesnt this cleanup include locally registered receivers ?

Yes, it does.

How come this recommendation doesnt apply to other locally defined objects ?

It does.

MMG
  • 3,226
  • 5
  • 16
  • 43
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks. You reassured me. Just one minor question regarding your last answer - are you saying that it is also recommended for other locally defined objects to be cleaned in onPause ? – AsafK May 24 '14 at 16:03
  • @AsafK: It would depend upon the nature of the object. If you do not need it while you are in the background, and cleaning it up would materially help your app or the user (e.g., free up heap space, reduce CPU consumption), then clean it up. – CommonsWare May 24 '14 at 16:07
  • I guess this should be balanced with the performance loss of obtaining this object when the activity is back in the forground. Anyway, thanks a lot, im in peace right now. – AsafK May 24 '14 at 16:13
  • @AsafK: "I guess this should be balanced with the performance loss of obtaining this object when the activity is back in the forground" -- precisely. So, for example, suppose that you are maintaining a local cache of some data read in from a file or database. If that data is not huge, the heap savings may be dwarfed by the I/O time to re-load it (and the UI effect that has on the user). In that case, aim to leave it alone. – CommonsWare May 24 '14 at 16:19
1

I dont quite understand why. The "official" explanation is that onDestory is not guaranteed to be called everytime the activity is destroyed

Like the docs explain. There might be extreme situations where the system has to get rid of your Activity to free some resources and will kill it without calling onDestroy()

Doesn't "killing the hosting process" means that there is an overall cleanup of the entire activities' resources ?

Correct.

Doesnt this cleanup include locally registered receivers ?

Correct.

How come this recommendation doesnt apply to other locally defined objects ? How come they are guaranteed to be cleaned and BroadcastReceivers not ?

They will all be cleared from memory if the Activity gets killed.

Just to clarify. People suggest to unregister receivers (or other components like a Camera instance) in onPause() because it is the first place where you can confidently release used resources since they will not be used in an Activity anymore after onPause() executes. Like Zapl says on this comment. If the Activity is killed, it doesn't matter if your unregistered in onPause() or in onDestroy() the system will wipe out everything regardless.

Community
  • 1
  • 1
Emmanuel
  • 13,083
  • 4
  • 39
  • 53
  • So according to what you say, IT IS safe to register/unregister BroadcastReceivers on onCreate/onDestroy. Am i correct ? – AsafK May 24 '14 at 15:13
  • I would still register them in `onResume()` and unregister them in `onPause()` just because it is what is preferred. Really, I do not use `LocalBroadcastManager` anymore. I use an event bus like [`Otto`](https://square.github.io/otto). – Emmanuel May 24 '14 at 15:18
  • "what is preferred" is the exact terminology im trying to understand. It seems like there is no real reason for that. – AsafK May 24 '14 at 15:22
  • It is preferred because there are the first points on the lifecycle where you can safely do so. – Emmanuel May 24 '14 at 15:23
  • ok, but what about cases where i want to handle a broadcast even when the activity is not in the foreground. Up until now, i thought this is impossible to be done. Now it looks like a valid (and safe) scenario. – AsafK May 24 '14 at 15:26
  • The `Activity` will not be on the foreground after `onPause()` gets called. – Emmanuel May 24 '14 at 15:29
  • I mean when the entire activity is not in the foreground (not visible). When im launching a different activity. – AsafK May 24 '14 at 15:30
  • Thats exactly my point. So unregistering BroadcastReceivers in onPause/onStop will cease the activity from getting broadcasts. Unregistering them in onDestory will enable the activity to handle broadcasts even when the activity is in the background or invisible. – AsafK May 24 '14 at 15:36