在单独的线程上运行广播接收器

时间:2015-01-28 07:35:01

标签: android multithreading

我有一个在进程主线程上运行的类。我想在这个类中实现一个广播接收器,它在一个单独的线程上运行。

我通过使内部类扩展线程&而尝试了这个。初始化此内部类中的处理程序,我可以将其赋予registerReceiver(BroadcastReceiver接收器,IntentFilter过滤器,String broadcastPermission,Handler调度程序),以便在此处理程序(附加到新创建的线程)上执行广播接收器。但是徒劳无功日志显示在主线程上调用onReceive。

请帮忙。(我已经看过一些关于如何使用registerReceiver(BroadcastReceiver接收器,IntentFilter过滤器,String broadcastPermission,Handler调度程序)的帖子,但没有任何帮助。)

3 个答案:

答案 0 :(得分:5)

我建议您使用HandlerThread而不是继承Thread

例如

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);

希望这对您的实验有所帮助;)

恩乔伊!

答案 1 :(得分:3)

使用HandlerThread时,请务必在取消注册BroadcastReceiver后退出该线程。如果没有,文件描述符(FD)泄漏发生在Linux级别,最后如果继续注册/取消注册,应用程序将崩溃。

unregisterReceiver(...);

然后
looper.quit();
或者
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
}

答案 2 :(得分:0)

我已经将LocalBroadcastReceiver分叉,以便能够在任意java线程上接收广播。

它对我有用。我添加了一个Looper param到

currentMonth

如果looper为null,则使用主线程循环器。

代码在这里:

https://github.com/sorenoid/LocalBroadcastManager/blob/master/LocalBroadcastManager.java