使用广播接收器启动异步任务(AsyncTask)

5
我试图在收到推送通知时更新UI的状态。为了做到这一点,我需要启动一个AsyncTask,执行一些网络操作,然后根据结果更新UI。
根据BroadcastReceiver的文档,从接收器中执行异步操作是不安全的,因为执行它的进程可能会在onReceive()返回后立即被杀死,假设该进程中没有其他"应用程序组件"。
BroadcastReceiver运行在自己的进程中还是与包含Activity相同的进程中?由于只要有UI更新,我就只关心任务完成与否,所以如果activity关闭,我不担心AsyncTask会死亡。假设BroadcastReceiver在与activity相同的进程中,从接收器中启动我描述的任务是否安全?
编辑:为了澄清,我在activity的onResume()中注册接收器,并在onPause()中注销它,因此只有在activity已经处于活动状态时才会接收意图。

如果BroadcastReceiver不安全,为什么不使用Service呢?它可以完成相同的任务,但不会出现你所说的问题。 - Andy
@Andy 我明白在所有情况下使用“服务”都是安全的,但我正在尝试确定在这种特定情况下是否真的有必要。 - jnackman
1
如果你仔细想一下,这是正确的。服务非常适合运行异步操作,因此不存在同样的限制。BroadcastReceivers主要用于其他事情,比如当系统发生某些事件时,而不是在通过网络更新数据时使用。因此称之为“广播”。而Service就是它的本意,一个在用户不需要知道的侧面运行的服务。希望这能让你明白。 - Andy
你可以使用一个 handler 来更新你的 UI,而不是直接在 BroadcastReceiver 中进行。这样你只需要将事件排队到你的活动消息队列中即可。 - broody
我建议按照下面的步骤立即将信息传递给Activity。从那里,您可以启动任何您需要的内容。 - Code Droid
4个回答

6

广播接收器并不在自己的进程中运行,而是在UI线程上运行。

只有当您的应用程序中没有其他活动或服务正在运行时,才会在onReceive方法返回后终止您的进程。

如果您的广播接收器是内部类的实例,并且仅在您的活动处于活动状态时接收,则在onReceive方法返回后,您的进程将不会被终止。



1
如果在您的AsyncTask中需要上下文,则我认为使用服务更好。如果不需要,使用AsyncTask也没有问题。

1

在蜂窝状版本(API11)之前,您必须使用服务。

自从蜂窝状版本(API11)以来,您可以使用goAsync()

应用程序可以在onReceive(Context,Intent)中调用此函数,以便在从该函数返回后仍然保持广播活动状态。这不会改变对广播相对响应的期望(在10秒内完成它),但确实允许实现将与之相关的工作移交到另一个线程中,以避免由于磁盘IO而使主UI线程出现故障。


0
我建议从广播接收器中使用startActivity(intent)。在intent中提供事件信息,您可以在bundle中设置参数。然后,在ActivityonStart()onCreate()中检查此标志。如果有标志,则从Activity启动AsyncTask
完全不需要使用服务,因为服务-活动之间存在绑定和通信限制。
请记住,您也可以使用startActivityForResult()。我认为您只想在广播接收器中传递和转发信息。
顺便说一下,活动不需要具有UI。它们可以是无面的活动。

正如你所提到的——“…活动不需要有UI界面”——那么我建议他使用服务。我认为活动用于UI,而服务用于后台任务。 - user1521536

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