在我的项目,我使用BroadcastReceiver
S作为从一个长期运行的线程回调(例如,通知下载结束的活动,并从工人发送一些响应数据Thread
,这样的活动可以显示相应的信息给用户.. )。 要使用BroadcastReceiver
的I必须要小心登记和我使用它,每次注销广播接收器,也有关心什么消息发送esspecialy当我用这种方法更多不同的操作(如下载,使得web服务电话等等..)。 并且还通过广播的意图,我也需要做出的对象发送自定义对象Parcelable
。
与此不同的做法,我也看到了这似乎是比我使用的方法更简单的回调方法的方法。 回调方法简单接口方法的实现,可用于实现像BroadcastRecaiver在应用程序的消息相同的效果。 这种方法不需要Parcelable实现返回复杂的对象,并没有使用像钥匙BroadcastReceiver
..我认为坏的部分是,我需要检查回调对象为空值之前,我想调用一个回调方法..并确保我从UI线程上执行运行的代码,所以我可以没有错误更新UI。
好吧,我希望你明白我的意思是说:)。
现在的问题是你认为的回调方法比较好(更轻,更清洁,更快速的..)比BroadcastReceiver
的方法,当使用只是内部的单个应用程序的? (请注意,我不使用Android的Service
后台工作..只是AsyncTask
和Thread
S)
谢谢!
这是一个非常有趣的问题,我碰到了同样的问题。 在我看来这两种机制可共使用,并使用正确的方法取决于你的使用情况。 这是考虑到一些问题,然后才决定。
使用回拨机制有一定好处,但也有局限性:
PRO
- 它是简单和直截了当地实现。
- 你得到的是彼此交互的组件之间的类型安全。
- 你可以返回任意对象。
- 它简化了测试,你只需要注入模拟回调在单元测试中(例如,通过或的Mockito类似的东西产生)。
反对
- 你必须切换到主线程才能做UI操作。
- 您只能有一个1对1的关系。 A 1到n的关系(观察者模式)也不是没有进一步的工作可实现。 在这种情况下,我宁愿Android的
Observer
/ Observable
机制。 - 正如你已经说了,你总要检查
null
调用回调函数之前,如果回调是可选的。 - 如果您的组件应该提供一种具有不同的服务功能,服务的API,你不希望有只有几个通用的回调函数的回调接口,你必须决定是否对每个服务功能,还是你提供一个特殊的回调接口提供了大量的回调函数一个回调接口。 在后一种情况下用于服务呼叫您的API所有回调客户端必须实现完整的回调接口虽然大多数方法体将是空的。 您可以解决此通过实现与空机构存根,并让您的回调客户端从存根继承,但这是不可能的,如果已经从另一个基类继承。 也许你可以使用某种动态代理回调(见http://developer.android.com/reference/java/lang/reflect/Proxy.html ),但后来它变得非常复杂,我想使用另一种机制。
- 回调调用客户端必须通过各种方法/组件进行传播,如果它不是由服务的调用者可以直接访问。
对于一些点BroadcastReceiver
-approach:
PRO
- 您实现组件之间的松耦合。
- 可以有一个1到n的关系(包括1到0)。
- 所述
onReceive()
方法总是在主线程上执行。 - 您可以在整个应用程序通知部件,因此通信组件没有“看”海誓山盟。
反对
- 这是一个非常通用的方法,使编组和由所传输的数据的数据编
Intent
是附加的误差源。 - 你必须让你的
Intent
的行动是唯一的(例如,通过前面加上包的名字),如果你想消除与其他应用程序的相关性,因为他们的初衷是为了应用之间做广播。 - 你必须管理
BroadcastReceiver
-registration和注销。 如果你想这样做,在一个更舒适的方式,你可以实现自定义的注释与要注册的动作来注释活动和实施基地Activity
的类,它注册和注销与IntentFilter
S IN它onResume()
RESP。 onPause()
方法。 - 正如你已经说过,这与发送的数据
Intent
必须实现Parcelable
接口,但还没有一个严格的尺寸限制,它会导致性能问题,如果你输送了大量的数据与你的Intent
。 见http://code.google.com/p/android/issues/detail?id=5878为上的讨论。 所以,如果你想发送的图像,例如你必须存放在仓库的临时和发送相应的ID或URL从您的接收器访问图像Intent
,从使用后的版本库中删除。 这就导致如果有几个接收器进一步的问题(当应的图像从库中删除,谁应该做的吗?)。 - 如果过度使用这种通报机制您的应用程序的控制流可能会隐藏起来,在调试的时候你最终的序列绘制图表
Intent
s到了解所引发的特定错误或为什么这个通知链在某些时候打破。
我认为,即使是移动应用应该有至少2层的结构基础:在UI层和芯层(与业务逻辑等)。 在一般情况下,长时间运行的任务是在自己的线程(也许通过执行AsyncTask
或HandlerThread
如果使用MessageQueue
S)核心层内,一旦这个任务已经完成了UI应该更新。 在一般以回调您实现组件之间的紧耦合,所以我宁愿只使用中的某一层,而不是跨层边界通信这种方法。 对于用户界面-和核心层我会使用之间的消息广播BroadcastReceiver
-approach,可以让你从分离逻辑层的UI层。
我不知道你用什么收获BroadcastReceiver
在您的案件。 回调或者更好的可能, Handlers
是做它的方式。 BroadcastReceiver
是不错的,当你不知道是谁的订户。
我就添加其他选项,你已经收到了其他伟大的答案...
您不必创建一个广播接收器接收意向。 在您的Android清单文件,您可以注册任何活动收到意图:
<activity android:name=".MyActivity">
<intent-filter >
<action android:name="intent.you.want.to.receive" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
....
</activity>
然后覆盖onNewIntent(Intent)
在您的活动的方法来接受它。
要发送的意图,使用Context.startActivity(Intent)
方法。 最有可能你会想在添加FLAG_ACTIVITY_SINGLE_TOP
标志你的意图,因此不会创建一个新的活动来说,如果一个已经在运行。
编辑:我只注意到你是一个单一的应用程序中运行。 因此,一个简单的回调可能是最好的。 上述方案中不工作在一个单一的应用,但更适合于不同的应用。 在这里我要离开这个只是在情况下,它可以帮助别人。 祝好运!
Broadcastreceivers应使用如果您需要发送跨应用程序的广播,而回调(或处理程序由Alex的建议)是更好地在你的情况下使用。
如果你想比这两个使用其他,请考虑使用观察者 (包含在Android界面)和委派。
对于委托请考虑此SO发布 。
not sure what the goal is , but if you wish to keep the same idea of using intent and broadcastReceiver , and want better performance and security than normal broadcastReceivers , you can try out this demo , available in the android support library :
http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/content/LocalServiceBroadcaster.html
if not , you can always use asyncTask , service , handlers , etc...