2013-04-11 68 views
1

我有一些关于Android的BroadcastReceiver的设计问题。Android BroadcastReceiver:线程模型和非重叠

我的情况如下:连接某个WiFi网络时,检测是否有强制门户,如果有,则对其进行身份验证。该场景涉及网络I/O并需要几秒钟才能完成(尤其是当您需要使用密码等待SMS时)。

通过调试BroadcastReceiver Wifi状态更改,我发现它在应用程序的主线程上调用。这是几分钟后我不知道的事情。我是这样说的,而不是问,因为这个问题也是我发现的结果。

在无线验证阶段,我应该处理用户突然断开连接(例如由于热点故障,用户走出范围......)并重新连接的情况,由避免两个广播重叠和可能取消认证最终失败。

当我发现BroadcastReceiver在主线程中执行后,我得出结论,我需要一个AsyncTask来执行网络I/O,但随意提出其他想法。

问题是:如果连续广播在长时间运行的任务中间被触发,我该如何阻止?事实上,AsyncTask可以被取消,但是我怎样才能存储一个AsyncTask的共享实例,以便从另一个BroadcastReceiver中取消它,而不会使我的生活过于复杂?

Android是否BroadcastReceiver s 事实上的单身人士还是Android会在每次需要播放新广播时创建一个新的已声明接收器实例吗?

回答

1

我来,我需要一个的AsyncTask来执行网络I/O

可能不是结论。

但随时提出其他想法

当别人指出的,一个IntentService是一个更好的主意。

问题的一部分是,你已经告诉我们几乎没有具体的关于你的接收器。特别是,您没有说明您是如何注册有问题的接收者:清单或registerReceiver()?理想的问题建议会考虑到这一点。 IntentService答案和这一个,假设你正在通过清单注册。

为Android BroadcastReceivers事实上的单身或没有Android的创建声明接收器的每一个它需要触发一个新的广播时间一个新的实例?

如果要注册清单中的接收器,为每个广播创建的BroadcastReceiver的新实例。更重要的是,Android没有任何信号传递,在这种情况下,您的流程需要坚持一次onReceive()返回,这就是为什么AsyncTask不是一个好主意,IntentService更好。

如果连续广播在长时间运行的任务中间被触发,我该如何阻止?

也许你不会“停止这样做”,因为很可能你所做的事不能以任何有意义的意义被“停止”,也不会让你的数据处于不确定状态。

如果您确实确信自己需要“停止该操作”,则需要创建自己的Service,该工具具有IntentService的某些特征(例如,它具有其后台线程),但允许您操纵命令队列,停止正在进行的工作等

,但我怎么能存储的AsyncTask的共享实例,以便从不同的BroadcastReceiver取消它没有我的生活变得复杂太多了?

你不能,容易,除了可能作为一个静态数据成员。但是由于在任务完成之前Android很可能会摆脱您的流程,因此使用AsyncTask并不是一个好主意。

+0

我在清单 – 2013-04-11 20:23:48

+0

中注册了我的接收器“可能您不会”停止该操作“,因为您很可能无法以任何有意义的意义”停止“您的操作,而不会使您处于不确定状态数据。” - 幸运的是在我的情况下,我可以取消注册SMS接收器(从代码)并杀死线程,但是您的评论在一般情况下是正确的 – 2013-04-11 20:37:52

1

对于需要一些时间执行的任务启动Service是一种很好的做法。

在你的情况下,我会使用IntentService。这个特定的Service在后台线程中执行,它也处理内部队列,所以如果你启动它两次,第二个任务将在第一个任务完成后执行。我强烈建议您使用IntentService而不是AsyncTask

1

BroadcastReceiverIntentService完美协作,它依次处理来自UI线程的传入意图。 Services guide有一个实现示例。您的BroadcastReceiver然后只需要调用IntentService。