Are Android's BroadcastReceivers started in a new thread?

佐手、 提交于 2019-11-27 18:59:02
Nick Pelly

The onReceive() method is always called on the main thread (which is also referred to as "UI thread"), unless you requested it to be scheduled on a different thread using the registerReceiver() variant:

Context.registerReceiver(BroadcastReceiver receiver,
                         IntentFilter filter,
                         String broadcastPermission,
                         Handler scheduler)

Are Android's BroadcastReceivers started in a new thread?

Usually but not always, it all depends on how you register it.

If you register your BroadcastReceiver using:

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

It will run in the main activity thread(aka UI thread).

If you register your BroadcastReceiver using a valid Handler running on a different thread:

registerReceiver (BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)

It will run in the context of your Handler

For example:

HandlerThread handlerThread = new HandlerThread("ht");
handlerThread.start();
Looper looper = handlerThread.getLooper();
Handler handler = new Handler(looper);
context.registerReceiver(receiver, filter, null, handler); // Will not run on main thread

Details here & here.

The onReceive() method is called on the main thread. So, in case all your access to the service class is done from within the main thread, you don't need any synchronization.

Also, you can specify the "android:process" receiver element attribute in the AndroidManifest.xml. See here. That way you can specify that the receiver runs as a separate process and isn't tied to the main UI thread.

Android Broadcast receivers are by default start in GUI thread (main thread) if you use RegisterReceiver(broadcastReceiver, intentFilter).

But it can be run in a worker thread as follows;

When using a HandlerThread, be sure to exit the thread after unregistering the BroadcastReceiver. If not, File Descriptor (FD) leaks occur in Linux level and finally the application gets crashed if continue to Register / Unregister.

unregisterReceiver(...);

Then looper.quit(); Or looper.quitSafely();

private Handler broadcastReceiverHandler = null;
private HandlerThread broadcastReceiverThread = null;
private Looper broadcastReceiverThreadLooper = null;

private BroadcastReceiver broadcastReceiverReadScans = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}

private void registerForIntents() {
    broadcastReceiverThread = new HandlerThread("THREAD_NAME");//Create a thread for BroadcastReceiver
    broadcastReceiverThread.start();

    broadcastReceiverThreadLooper = broadcastReceiverThread.getLooper();
    broadcastReceiverHandler = new Handler(broadcastReceiverThreadLooper);

    IntentFilter filterScanReads = new IntentFilter();
    filterScanReads.addAction("ACTION_SCAN_READ");
    filterScanReads.addCategory("CATEGORY_SCAN");

    context.registerReceiver(broadcastReceiverReadScans, filterScanReads, null, broadcastReceiverHandler);
}

private void unregisterIntents() {
    context.unregisterReceiver(broadcastReceiverReadScans);
    broadcastReceiverThreadLooper.quit();//Don't forget
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!