运行 在单独的线程上广播接收器
Running broadcast receiver on a separate thread
我有一个在进程的主线程上运行的 class。我想在此 class 中实现广播接收器,它在单独的线程上运行。
我通过制作内部 class 扩展线程并在此内部 class 中初始化处理程序来尝试此操作,我可以将其提供给 registerReceiver(BroadcastReceiver 接收器,IntentFilter 过滤器,String broadcastPermission,Handler scheduler ) 用于在此处理程序上执行广播接收器(附加到新创建的线程)。但徒劳无功。日志显示正在主线程上调用 onReceive。
请帮忙。(我看过一些关于如何使用 registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) 的帖子,但没有任何帮助)。
我建议您应该使用 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);
希望这对您的实验有所帮助 ;)
开心!
使用HandlerThread 时,请务必在注销BroadcastReceiver 后退出线程。否则,文件描述符 (FD) 泄漏会发生在 Linux 级别,如果继续注册/取消注册,应用程序最终会崩溃。
unregisterReceiver(...);
然后
looper.quit();
或者
looper.quit安全();
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
}
我已经分叉 LocalBroadcastReceiver 以便能够在任意 java 线程上接收广播。
对我有用。我向
添加了一个 Looper 参数
public void registerReceiver(Context act, IntentFilter filt, Looper looper)
如果looper为null,则使用主线程looper。
代码在这里:
https://github.com/sorenoid/LocalBroadcastManager/blob/master/LocalBroadcastManager.java
我有一个在进程的主线程上运行的 class。我想在此 class 中实现广播接收器,它在单独的线程上运行。
我通过制作内部 class 扩展线程并在此内部 class 中初始化处理程序来尝试此操作,我可以将其提供给 registerReceiver(BroadcastReceiver 接收器,IntentFilter 过滤器,String broadcastPermission,Handler scheduler ) 用于在此处理程序上执行广播接收器(附加到新创建的线程)。但徒劳无功。日志显示正在主线程上调用 onReceive。
请帮忙。(我看过一些关于如何使用 registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) 的帖子,但没有任何帮助)。
我建议您应该使用 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);
希望这对您的实验有所帮助 ;)
开心!
使用HandlerThread 时,请务必在注销BroadcastReceiver 后退出线程。否则,文件描述符 (FD) 泄漏会发生在 Linux 级别,如果继续注册/取消注册,应用程序最终会崩溃。
unregisterReceiver(...);
然后
looper.quit();
或者
looper.quit安全();
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
}
我已经分叉 LocalBroadcastReceiver 以便能够在任意 java 线程上接收广播。
对我有用。我向
添加了一个 Looper 参数public void registerReceiver(Context act, IntentFilter filt, Looper looper)
如果looper为null,则使用主线程looper。
代码在这里:
https://github.com/sorenoid/LocalBroadcastManager/blob/master/LocalBroadcastManager.java