Jun 22, 2010
How can I best implement a BroadcastReceiver that may need to "consume" the current broadcast (via abortBroadcast()), but it first needs to perform some non-trivial work to determine whether or not the broadcast should be consumed.
View 4 Replies
The problem is that if the non-trivial work takes more than 10 seconds then the receiver is considered to be blocked by the system and may be killed.
I realise that long-running operations should not be performed in the onReceive() method of receivers for that very reason, and should instead be handed-off to an appropriate service. However, if the current broadcast is to be consumed, then the abortBroadcast() method must be called within the onReceive() method before it returns. If some processing is required to determine whether the current broadcast should be consumed or not, then things can get tricky.
I'm developing an app that can consume some (but not all) inbound SMS messages. For any given SMS message it will need to perform some analysis based on the sender's phone number and the message body (including database lookups) in order to determine if the message is one that is relevant to the app or not. In the vast majority of cases this will take less than 10 seconds, but it is possible that it could take longer on rare occasions.
To get around this I'm considering the following solution.
1. On receiving a broadcast for a received SMS, my receiver starts a background thread to perform the required analysis and handle the message if appropriate. 2. The main thread (currenly executing the onReceive() method) waits until either the background thread has finished its work, or 8 seconds have elapsed, whichever occurs first. 3. If the background thread finished within the allotted time (which should happen most of the time), then the main thread calls abortBroadcast() or not, (depending on the result of the analysis) and returns normally. 4. If the background thread did NOT finish within 8 seconds, then the main thread stops the background thread and instead starts a service to perform the work. In this case it does NOT call abortBroadcast(), and the broadcast will be passed to other receivers (eg the default messaging app) regardless of whether or not the service ends up handling the message. While not an ideal outcome, it is acceptable.