Android BroadcastReceiver还是简单的回调方法?

Cat*_*ata 54 multithreading android callback broadcastreceiver

在我的项目中,我使用BroadcastReceivers作为来自长时间运行线程的回调(例如,通知活动下载已完成并从Worker发送一些响应数据,Thread以便活动可以向用户显示相应的消息......).要使用BroadcastReceivers,我每次使用时都必须小心注册和取消注册广播接收器,并且当我使用此方法进行更多不同的操作(例如下载,进行WebService调用等)时,还必须特别注意要发送的消息. ..).而且,通过广播的意图发送自定义对象我还需要制作对象Parcelable.

与这种方法不同,我还看到了回调方法方法,它看起来比我使用的方法更简单.回调方法是简单的接口方法实现,可用于实现与应用程序消息传递中的BroadcastRecaiver相同的效果.这种方法不需要Parcelable实现来返回复杂的对象而且它不使用类似的键BroadcastReceiver.我认为不好的部分是我需要在调用回调方法之前检查回调对象的null值.还要确保我从UI线程上的实现运行代码,这样我就可以更新UI而不会出错.

好的,我希望你明白我的意思:).

现在问题是你认为回调方法比BroadcastReceiver单个应用程序内部使用的方法更好(更轻,更干净,更快......)?(请注意,我没有使用Android Service进行后台工作..只是AsyncTaskThreads)

谢谢!

And*_*ber 83

这是一个非常有趣的问题,我遇到了同样的问题.在我看来,这两种机制都可以完全使用,正确的使用方法取决于您的使用案例.在决定之前,需要考虑以下几点.

使用回调机制有一些好处,但也有局限性:

PRO

  • 实施简单直接.
  • 您可以在彼此交互的组件之间获得类型安全性.
  • 您可以返回任意对象.
  • 它简化了测试,因为您只需要在单元测试中注入模拟回调(例如通过mockito或类似的东西生成).

魂斗罗

  • 您必须切换到主线程才能进行UI操作.
  • 您只能拥有一对一的关系.没有进一步的工作,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注册和注销.如果您想以更舒适的方式执行此操作,则可以实现自定义注释以使用应注册的操作注释您的Activity,并实现在其resp中ActivityIntentFilters进行注册和取消注册的基类onResume().onPause()方法.
  • 正如您已经说过的,与Intent必须实现Parcelable接口一起发送的数据,但是还有严格的大小限制,如果您使用您的数据传输大量数据,则会导致性能问题Intent.有关该问题的讨论,请参阅http://code.google.com/p/android/issues/detail?id=5878.因此,如果您要发送图像,例如,您必须将它们临时存储在存储库中,并发送相应的ID或URL以从您的接收方访问该图像,并Intent在使用后将其从存储库中删除.如果有多个接收器,那么这会导致进一步的问题(何时应该从存储库中删除图像以及谁应该这样做?).
  • 如果过度使用这种通知机制,应用程序的控制流可能会被隐藏,并且在调试时最终会绘制带有Intents 序列的图形,以了解触发特定错误的原因或者为什么此通知链在某些时候被破坏.

在我看来,即使是移动应用程序也应该拥有至少2层的架构:UI层和核心层(具有业务逻辑等).通常,长时间运行的任务在核心层内部的自己的线程中执行(可能通过AsyncTask或者HandlerThread如果使用MessageQueues),并且一旦完成此任务就应该更新UI.通常使用回调可以实现组件之间的紧密耦合,因此我更倾向于仅在一个层中使用此方法,而不是跨层边界进行通信.对于BroadcastReceiverUI层和核心层之间的消息广播,我将使用-approach,它允许您将UI层与逻辑层分离.

  • 您可以使用[`LocalBroadcastManager`](http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html)将广播保持在您的应用的本地.这有助于防止应用程序交叉的某些问题,并且可以放心数据的运行位置. (3认同)

Ale*_*tin 6

BroadcastReceiver在你的情况下,我看不到你获得了什么.回调或者更好的可能Handlers是做到这一点.BroadcastReceiver如果您不知道订阅者是谁,那就很好.