1

我有一些关于 Android 的设计问题BroadcastReceiver

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

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

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

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

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

AndroidBroadcastReceiver事实上的单例还是 Android 每次需要触发新的广播时都会创建一个声明接收器的新实例?

4

3 回答 3

1

Service为需要一些时间执行的任务启动一个很好的做法。

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

于 2013-04-11T19:55:36.740 回答
1

BroadcastReceivers 与IntentService完美配合,该服务按顺序处理来自 UI 线程的传入意图。服务指南有一个实施示例。然后,您BroadcastReceiver只需调用 IntentService。

于 2013-04-11T19:55:55.000 回答
1

我得出的结论是我需要一个 AsyncTask 来执行网络 I/O

可能不是。

但随时提出其他想法

正如其他人指出的那样,anIntentService是一个更好的主意。

部分问题是您几乎没有告诉我们有关您的接收器的任何具体信息。特别是,您没有说明您是如何注册有问题的接收器的:清单,还是registerReceiver()?理想情况下,对您的问题的建议会考虑到这一点。答案,以及这个IntentService,假设您正在通过清单进行注册。

Android BroadcastReceivers 是事实上的单例,还是Android 每次需要触发新广播时都会创建一个声明接收器的新实例?

如果您在清单中注册接收器,BroadcastReceiver则会为每个广播创建一个新的实例。更重要的是,在这种情况下,没有任何信号向 Android 表明您的进程需要在onReceive()返回后继续存在,这就是为什么这AsyncTask不是一个好主意,而是一个更好的主意IntentService

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

可能您不会“停止”,因为很有可能您正在做的事情不能在任何有意义的意义上“停止”而不会给您的数据留下不确定的状态。

如果您真的非常有信心需要“停止”,您将需要创建自己的Service具有某些特征IntentService(例如,它具有其后台线程)但允许您操作命令队列,停止-进度工作等

但是如何存储 AsyncTask 的共享实例以便从不同的 BroadcastReceiver 取消它而不会使我的生活变得太复杂?

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

于 2013-04-11T20:02:46.180 回答