BroadcastReceiver: goAsync()与onReceive()中的AsyncTask的区别

4
我有一个BroadcastReceiver(或者更具体地说,一个AppWidgetProvider),我需要在onReceive()方法中进行一些网络操作......不是特别长时间的(应该在10秒内完成,如果没有,我很高兴(*)将它们超时)。
目前,我从onReceive()执行AsyncTask,以便网络操作不会阻塞UI线程,但我看到BroadcastReceiver还提供了goAsync()方法,用于大致相同的目的。
我很难找到关于在此上下文中使用AsyncTaskgoAsync()之间确切区别的解释......何时使用其中一个,何时使用另一个?

(*) 我提到我的网络操作和后续处理通常会在10秒内完成(**),这是我了解到在从onReceive()返回后BroadcastReceiver被杀死之前的时间。然而,在特别具有挑战性的条件下(不可靠的网络、缓慢的设备),最好允许操作继续进行超过10秒。在这方面,上述方法中哪一个更好呢?至少对于goAsync(),文档建议你仍然应该在10秒内完成包装事物。但是对于AsyncTask,是否可能生成AsyncTask并使doInBackground()方法运行超过10秒...如果它被声明为BroadcastReceiver的静态内部类,它是否会在BroadcastReceiver的生命周期之外存在?

(**) 编辑:10秒的限制是在BroadcastReceiver.onReceive()的文档中...具体来说:

当它在主线程上运行时,您不应该在其中执行长时间运行的操作(系统允许10秒超时,否则将考虑接收器被阻塞并将其视为可杀死的候选项)。

1
在哪里说接收器在10秒后被“杀死”了? - Tim
1
我在我的帖子中添加了一个参考。 - drmrbrewer
2个回答

2

在广播接收器中使用AsyncTask是一种不好的做法,尽量避免使用,因为系统可能会杀死你的进程并且onReceive没有返回值的保证。

goAsync()返回一个PendingResult对象,只要你在其上调用PendingResult.finish(),系统就认为该接收器仍然存活。


所以,使用goAsync(),你可以保持接收器的存活时间超过10秒...基本上只要您需要完成操作的时间就可以了?当然,可能仍然有一个"预期"它应该在10秒内完成,但如果需要,您可以拥有更长的时间?至于AsyncTask...我曾经认为,如果它被声明为静态内部类,则具有独立于父级(接收器)的生命,因此在父级结束时不应该被终止。也许我需要找到一个关于这个主题的好教程... - drmrbrewer
@drmrbrewer 的观点很好。我正在尝试学习同样的东西。你得出了什么结论吗? - c0dehunter
据我回忆,我坚持使用AsyncTask,但首先启动了一个Service,然后从那里启动了AsyncTask - drmrbrewer

1

goAsync:

如果你在 BroadcastReceiver::onReceive 返回之前调用 goAsync,当一段时间后有新的广播到来时,Android 系统会调用相同的接收器,即你调用 goAsync 的同一个接收器实例。

AsyncTask:

如果你在 BroadcastReceiver::onReceive 返回之前调用 AsyncTask,当一段时间后有新的广播到来时,尽管进程仍在运行,Android 系统可能会调用一个新的接收器,你不能确定该接收器是否与你之前调用 AsyncTask 的接收器相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接