在 BroadcastReceiver 中启动一个新线程是否安全?
Is it safe to start a new thread in a BroadcastReceiver?
我需要在 BroadcastReceiver
中执行网络操作。
到目前为止,我是通过启动一个新线程来实现的:
@Override
public void onReceive(Context context, Intent intent) {
new Thread(new Runnable() {
public void run() {
// network stuff...
}
}).start();
}
是否存在线程未完成就杀死进程的风险?
使用 IntentService
更好吗?还有其他更好的方法吗?
Is there any risk that the process will be killed before the thread is done?
如果此接收器是通过清单注册的,是的。
如果此接收器是通过 registerReceiver()
注册的,您的进程的生命周期将由其他 运行 组件决定。
Is it better to use an IntentService instead?
如果这项工作将超过几毫秒,恕我直言,是的,可能与 WakefulBroadcastReceiver
一致。
Any other better approach?
a goAsync()
option on BroadcastReceiver
可以让您有 window 的时间在触发 ANR 之前在另一个线程中完成工作。我避免这种情况,因为它没有很好的记录。例如,它没有直接解决您的问题:当这个后台线程正在工作时,进程的重要性是什么?这是否能让设备保持足够长的唤醒时间来完成我们的工作?等等。我将使用 IntentService
或其他形式的 Service
,以便我更好地理解合约。
这不是最好的主意。 BroadcastReceiver 的生命周期持续到完成调用 onReceive() 所需的时间,之后它被销毁。如果您要启动 运行 一个新线程,则 BroadcastReceiver 有可能在线程完成之前被终止,这将导致一些意外行为。
更好的选择是启动后台服务,就像你说的那样。
以下是我测试的一些实用信息:
onResume
持续 10 秒。
Thread
本身持续时间更长。在空闲设备上大约 7 分钟。
- 填充大约 450MB RAM(在 4GB 设备上)将停止线程并垃圾收集所有内容。
- 如果在设备处于睡眠模式(通过
AlarmManager
)时触发 BroadcastRecevier
,可靠性会更差。大多数情况下 运行 没问题,但有时 运行 小时后 phone 解锁,有时 运行 根本不解锁。 (我也使用了 wake lock
,但我不认为它有什么不同。)
在某些情况下这可能值得尝试,因为根据我的经验,android 特定的线程解决方案也不是很可靠。也许对于像获取最新天气预报的小部件按钮之类的东西...
我需要在 BroadcastReceiver
中执行网络操作。
到目前为止,我是通过启动一个新线程来实现的:
@Override
public void onReceive(Context context, Intent intent) {
new Thread(new Runnable() {
public void run() {
// network stuff...
}
}).start();
}
是否存在线程未完成就杀死进程的风险?
使用 IntentService
更好吗?还有其他更好的方法吗?
Is there any risk that the process will be killed before the thread is done?
如果此接收器是通过清单注册的,是的。
如果此接收器是通过 registerReceiver()
注册的,您的进程的生命周期将由其他 运行 组件决定。
Is it better to use an IntentService instead?
如果这项工作将超过几毫秒,恕我直言,是的,可能与 WakefulBroadcastReceiver
一致。
Any other better approach?
a goAsync()
option on BroadcastReceiver
可以让您有 window 的时间在触发 ANR 之前在另一个线程中完成工作。我避免这种情况,因为它没有很好的记录。例如,它没有直接解决您的问题:当这个后台线程正在工作时,进程的重要性是什么?这是否能让设备保持足够长的唤醒时间来完成我们的工作?等等。我将使用 IntentService
或其他形式的 Service
,以便我更好地理解合约。
这不是最好的主意。 BroadcastReceiver 的生命周期持续到完成调用 onReceive() 所需的时间,之后它被销毁。如果您要启动 运行 一个新线程,则 BroadcastReceiver 有可能在线程完成之前被终止,这将导致一些意外行为。
更好的选择是启动后台服务,就像你说的那样。
以下是我测试的一些实用信息:
onResume
持续 10 秒。Thread
本身持续时间更长。在空闲设备上大约 7 分钟。- 填充大约 450MB RAM(在 4GB 设备上)将停止线程并垃圾收集所有内容。
- 如果在设备处于睡眠模式(通过
AlarmManager
)时触发BroadcastRecevier
,可靠性会更差。大多数情况下 运行 没问题,但有时 运行 小时后 phone 解锁,有时 运行 根本不解锁。 (我也使用了wake lock
,但我不认为它有什么不同。)
在某些情况下这可能值得尝试,因为根据我的经验,android 特定的线程解决方案也不是很可靠。也许对于像获取最新天气预报的小部件按钮之类的东西...