Are Android's BroadcastReceivers started in a new thread?

前端 未结 5 1302
难免孤独
难免孤独 2020-12-05 00:01

If I have an inner class that extends BroadcastReceiver within my Service class, should I care about synchronization, when the BroadcastRecei

相关标签:
5条回答
  • 2020-12-05 00:31

    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.

    0 讨论(0)
  • 2020-12-05 00:31

    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.

    0 讨论(0)
  • 2020-12-05 00:38

    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
    }
    
    0 讨论(0)
  • 2020-12-05 00:39

    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)
    
    0 讨论(0)
  • 2020-12-05 00:51

    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.

    0 讨论(0)
提交回复
热议问题