Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running broadcast receiver on a separate thread

I have a class which runs on process's main thread. I want to implement a broadcast receiver in this class which runs on a separate thread.

I tried this by making a inner class extending thread & intializing a handler in this inner class, which i can give to registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) for executing broadcast receiver on this handler(which is attached to newly created thread). but in vain. Logs show onReceive is being called on main thread.

please help.(i have seen some posts on how to use registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler), but not of any help).

like image 766
Learner Avatar asked Jan 28 '15 07:01

Learner


2 Answers

I would suggest you should use HandlerThread instead of subclassing a Thread

for example

HandlerThread handlerThread = new HandlerThread("DifferentThread" , android.os.Process.THREAD_PRIORITY_BACKGROUND);
handlerThread.start();
Looper looper = handlerThread.getLooper();
private Handler handler = new Handler(looper, this);
// Register the broadcast receiver to run on the separate Thread
registerReceiver (myReceiver, intentFilter, broadcastPermission, handler);

Hope this will help in your Experiment ;)

Njoy!

like image 88
Shubhang Malviya Avatar answered Oct 08 '22 19:10

Shubhang Malviya


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
}
like image 3
Samantha Avatar answered Oct 08 '22 21:10

Samantha