Android的BroadcastReceivers是否在新线程中启动?

时间:2011-03-22 16:57:44

标签: android multithreading concurrency broadcastreceiver

如果我在BroadcastReceiver类中有一个扩展Service的内部类,我应该关心同步,当BroadcastReceiver类读取/写入Service中的对象时}类? 或者换句话说:BroadacstReceiver的{​​{1}}方法是在一个额外的线程中开始的吗?

5 个答案:

答案 0 :(得分:40)

onReceive()方法总是在主线程(也称为“UI线程”)上调用,除非您使用registerReceiver()变体请求在不同的线程上调度它:

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

答案 1 :(得分:20)

  

Android的BroadcastReceivers是否在一个新线程中启动了?

通常但并非总是如此,这完全取决于您如何注册。

如果您使用以下注册BroadcastReceiver

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

它将在 主要活动线程(又名UI线程) 中运行。

如果您使用在其他主题上运行的有效BroadcastReceiver注册Handler

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

它将在 Handler

的上下文中运行

例如:

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

详情here& here

答案 2 :(得分:18)

The onReceive() method is called on the main thread.因此,如果您对所有服务类的访问都是在主线程内完成的,则不需要任何同步。

答案 3 :(得分:2)

此外,您可以在AndroidManifest.xml中指定“android:process”接收器元素属性。见here。这样,您可以指定接收器作为单独的进程运行,并且不依赖于主UI线程。

答案 4 :(得分:0)

默认情况下,Android Broadcast接收器在GUI线程(主线程)中启动  public override void SetParameters(ParameterCollection parameters) { Id = null; return base.SetParameters(ParametersCollection parameters) }

但是它可以按如下方式在工作线程中运行;

使用HandlerThread时,请确保在注销BroadcastReceiver后退出线程。否则,Linux级别会发生文件描述符(FD)泄漏,如果继续注册/注销,最终会使应用程序崩溃。

unregisterReceiver(...);

然后 looper.quit(); 要么 looper.quitSafely();

RegisterReceiver(broadcastReceiver, intentFilter).