Tips you may have missed about broadcasts and BroadcastReceivers
I, as an Android developer, have used BroadcastReceiver a million times. I thought I knew everything about it until someday there was a subtle bug regarding one of these BroadcastReceivers and so I read its official documentation from A to Z to sort out the bug.
What follows are some tips to keep in mind when using broadcasts and BroadcastReceivers.
Watch for changes to system broadcasts when updating targetSdkVersion
Whenever we upgrade targetSdkVersion
we should always check to see if there are any changes regarding system broadcasts.
For instance, starting from Android 7.0 (API level 27) there are no more system broadcasts for ACTION_NEW_PICTURE
and ACTION_NEW_VIDEO.
Or starting from Android 9.0 (API level 28) a BroadcastReceiver registered for broadcasts of type NETWORK_STATE_CHANGED_ACTION
no longer receives information about user’s location or any personally identifiable data.
Beware of the code you put inside onReceive
The code put inside onReceive
of a BroadcastReceiver runs on the main thread. So if the code takes long to complete then from OS’s perspective the BroadcastReceiver is blocked and is eligible to be killed. To be more precise if the code inside onReceive
takes more than 10 seconds to complete then the BroadcastReceiver is considered blocked.
BroadcastReceivers defined in AndroidManifest.xml
Suppose we have defined a BroadcastReceiver named AirplaneModeReceiver
to react to ACTION_AIRPLANE_MODE_CHANGED
broadcasts and we have registered it in AndroidManifest.xml using a <receiver>
tag. Then each time a broadcast of type ACTION_AIRPLANE_MODE_CHANGED
is received, a new instance of AirplaneModeReceiver
gets created to handle the broadcast.
Dynamic BroadcastReceivers
BroadcastReceivers that could be defined using a <receiver>
tag in AndroidManifest.xml are pretty limited. In other words, to react to most of system broadcasts a BroadcastReceiver should be dynamically registered and unregistered using Context.registerReceiver()
and Context.unregisterReceiver()
methods.
If such a BroadcastReceiver is defined in AndroidManifest.xml it does not receive the intended broadcast.
Internal broadcasts
Sometimes we use broadcasts for communications local to our app. In such cases, we could use LocalBroadcastManager
for sending/receiving broadcasts. The LocalBroadcastManager
is much more efficient because there is no IPC overhead and allows you to avoid thinking about security issues related to sending/receiving broadcasts.
That’s it!