在BroadcastReceiver中启动新线程是否安全?

时间:2016-08-24 15:42:47

标签: android broadcastreceiver

我需要在BroadcastReceiver中执行网络操作。

到目前为止,我通过开始一个新线程来实现它:

@Override
public void onReceive(Context context, Intent intent) {
    new Thread(new Runnable() {
        public void run() {
            // network stuff...
        }
    }).start();
}

在线程完成之前是否存在杀死进程的风险?

使用IntentService代替它会更好吗?还有其他更好的方法吗?

3 个答案:

答案 0 :(得分:9)

  

在线程完成之前是否存在杀死进程的风险?

如果此接收者是通过清单注册的,是的。

如果此接收者是通过registerReceiver()注册的,则您的过程的生命周期将由其他正在运行的组件确定。

  

使用IntentService会更好吗?

如果这项工作将持续几毫秒,恕我直言,是的,可能与WakefulBroadcastReceiver一致。

  

还有其他更好的方法吗?

在触发ANR之前,有a goAsync() option on BroadcastReceiver为您提供了在另一个线程中工作的窗口。我避免这样做,因为它的记录很少。例如,它没有直接解决您的问题:当后台线程正在执行其工作时,进程的重要性是什么?这是否能使设备保持足够长的时间才能完成工作?等等。我将使用IntentService或其他形式的Service,我可以更好地了解合同。

答案 1 :(得分:1)

这不是最好的主意。 BroadcastReceiver的生命周期持续到完成调用onReceive()所需的时间,然后它被销毁。如果你开始运行一个新线程,那么在线程完成之前有可能会杀死BroadcastReceiver,这会导致一些意想不到的行为。

更好的选择是启动后台服务,就像你说的那样。

答案 2 :(得分:0)

以下是我测试中的一些实用信息:

  • onResume持续 10秒
  • Thread本身的使用寿命更长。在闲置的设备上大约 7分钟
  • 在4GB设备上填充大约 450MB RAM 会停止线程并垃圾回收所有内容。
  • 如果在设备处于睡眠模式时(由BroadcastRecevier触发AlarmManager,则可靠性会更差。大多数情况下,它运行良好,但有时会在解锁手机后数小时后运行,有时甚至根本无法运行。 (我也使用了wake lock,但我认为它没有太大的区别。)

这在某些情况下可能值得尝试,因为根据我的经验,特定于android的线程解决方案也不是很可靠。也许是像可获取最新天气预报的小部件按钮之类的东西。