2

I wondered how BroadcastReceivers handle multiple message requests (broadcast intents).

Assuming a BroadcastReceiver still processing a message/intent on the UI thread and at the same time another broadcast message(s) is/are fired from some other thread(s). Will the subsuquent broadcast messages be put into a queue or something?

Thx

stdout
  • 2,471
  • 2
  • 31
  • 40

2 Answers2

3

I think what you want is here: http://codetheory.in/android-broadcast-receivers/

Asynchronous Processing

Generally after the execution of onReceive() of the receiver class is finished, the Android system is allowed to recycle the receiver, i.e., another intent can be passed to it. For potentially long running operations it is recommended to trigger a service instead on the context object passed to it. This is a reason why any asynchronous operation wasn’t allowed to perform till API level 11. But that has changed now.

Since API 11, if you want to pass on the processing of some task in another thread you could do something like this:

// Sample code from: http://stackoverflow.com/a/22741384

final PendingResult result = goAsync();
Thread thread = new Thread() {
   public void run() {
      int i;
      // Do processing
      result.setResultCode(i);
      result.finish();
   }
};
thread.start();

Using goAsync() we returned an object of the type PendingResult on which calling the finish() method indicates the Android system that the receiver is no more alive and can be recycled.

What he is saying here, is that your receiver is recycled AFTER it completes execution, meaning that you can receive one at a time, but you can receive many.

EDIT ON COMMENTS
I stand slightly corrected by a statement made by an Android Framework Engineer, Dianne Hackborn (https://groups.google.com/forum/#!topic/android-developers/ClIGNuGJUts):

A particular receiver can only process one broadcast at a time. As each broadcast happens, it is processed to determine the targets it should go to, and dispatched into the message queue for each target.

So it seems it does create a queue for you. Honestly I would not recommend relying too much on broadcasts, they are tricky in the best of times, and I have found Message Handlers FAR more reliable. But there are times when they are necessary.

I think the best option here is to actually go and try it and see for yourself what happens.

Quintin Balsdon
  • 5,484
  • 10
  • 54
  • 95
  • 1
    I'm a bit confused here. I can received one at a time or received many? Or you're saying you can process one at a time but may receive many? The question is what if I (as a BroadcastReceiver) receive another broadcast message whilst I'm still processing one. Will it be queued or overlaps the currently executed one? – stdout Aug 10 '15 at 11:08
  • So you will receive one, but you cannot receive another one until the receiver is recycled (when it has completed executing). – Quintin Balsdon Aug 10 '15 at 11:20
  • Hence they're sort of discarded then? – stdout Aug 10 '15 at 11:22
  • 2
    The answer is: They will not be queued for you. Your receiver can only process one at a time, and if another is received WHILE you are processing, it will not be processed and will be lost. This is why most people thread the response code, so that the receiver is exited and recycled as quickly as possible. – Quintin Balsdon Aug 10 '15 at 11:22
  • Thank you indeed. I'd thought that they're put into the main thread's looper message queue and processed from there, instead having them lost. – stdout Aug 10 '15 at 11:42
  • 1
    It seems as though they are queued for you (see edit above), but relying on it is going to be tricky. I have done a lot of research for you at this point - if you feel this is an acceptable answer, please mark it as such – Quintin Balsdon Aug 10 '15 at 11:57
  • Hi again mate. I've actually seen that before but she's talking about particular component message queue I suppose, not the queue that I thought the concerning BroadcastReceiver (or any other class) should have. – stdout Aug 10 '15 at 17:14
0

I'm just going to give an example that I used for Bluetooth connection that shows how you use an IntentFilter to pick up different actions:

IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
getApplication().registerReceiver(mReceiver, filter);

And the BroadcastReceiver:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {     
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {          
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                Toast.makeText(getApplicationContext(), "Device not found", Toast.LENGTH_LONG).show();
        }
    }
};

I hope this helps you.

M0CH1R0N
  • 756
  • 9
  • 19