安卓的BroadcastReceiver或简单的回调方法? [英] Android BroadcastReceiver or simple callback method?

查看:181
本文介绍了安卓的BroadcastReceiver或简单的回调方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目,我使用的BroadcastReceiver 译文]从一个长期运行的线程回调(例如,通知将下载完成的活动,从发送一些响应数据工人,这样的活动可以显示相应的信息给用户。)。 要使用的BroadcastReceiver 的I要小心登记和我使用它,每次注销广播接收器,也有关心什么消息esspecialy发送时,我使用这种方法更多不同的操作(如下载,使得WebService的调用等)。并且还通过广播的意图,我也需要使对象 Parcelable 发送自定义对象。

In my projects I am using BroadcastReceivers as a callback from a long running thread (eg. notify the activity that a download was finished and send some response data from a Worker Thread so that the activity can display the appropriate message to the user..). To use BroadcastReceivers I have to be careful to register and unregister the broadcast receiver each time I am using it and also have to care of what messages to send esspecialy when I am using this method for more different actions(like downloading, making WebService calls etc..). And also to send custom Objects through Broadcast's intent I need also to make the objects Parcelable.

与此不同的方法,我还看到这似乎是比我使用的方法简单的回调方法的方法。回调方法都是简单的接口中的方法实现,可用于实现像BroadcastRecaiver在应用程序的消息同样的效果。 这种方法不需要Parcelable实施返回复杂的对象,它不使用的按键,例如的BroadcastReceiver ..我觉得不好的是,我需要检查回调对象为空值之前,我想调用一个回调方法..而且也确保我从UI线程上执行运行code这样我就可以更新UI没有错误。

Unlike this approach, I have seen also the callback methods approach which appears to be simpler than the method I use. Callback methods are simple Interface methods implementation that can be used to achieve the same effect like the BroadcastRecaiver's in app messaging. This approach doesn't need Parcelable implementation to return complex objects and it doesn't use keys like BroadcastReceiver.. I think the bad part is that I need to check the callback object for null value before I want to call a callback method.. and also to make sure I am running the code from the implementation on the UI thread so I can update the UI without errors.

好吧,我希望你明白我的意思是说:)。

Ok, I hope you understood what I meant to say :).

现在的问题是你认为的回调方法比较好(更轻,更清洁,更快速..)比当使用仅仅在单一的的BroadcastReceiver 办法应用? (请注意,我没有使用Android的服务的后台工作..只是的AsyncTask S)

Now the question is do you think that the callback method is better (lighter, cleaner, faster..) than the BroadcastReceiver approach when are used just inside of a single application? (Note that I am not using Android Service for background work.. just AsyncTask and Threads)

感谢您!

推荐答案

这是一个非常有趣的问题,我遇到了同样的问题。在我看来这两种机制可以一起使用,正确的方法来使用取决于你的使用情况。这里有几点需要考虑后再决定。

This is a very interesting question and I ran into the same problem. In my opinion both mechanisms can be used altogether and the right approach to use depends on your use case. Here are some points to be taken into account before deciding.

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

Using the callback-mechanism has some benefits, but there are also limitations:

PRO

  • 这是简单和直接的实现。
  • 您获取彼此交互的组件之间的类型安全。
  • 您可以返回任意对象。
  • 在它简化了测试,你只需要注入模拟回调(例如通过的Mockito或类似的东西产生)的单元测试。

魂斗罗

  • 您必须为了做UI操作切换到主线程。
  • 您只能有一个1对1的关系。 A 1对N的关系(观察者模式)不变现没有进一步的工作。在这种情况下,我会preFER Android的观察 / 观测机制。
  • 正如你已经说了,你总是调用回调函数,如果回调是可选的前检查
  • 如果您的组件应该提供一种不同的服务功能,服务API,你不希望有只有少数通用回调函数的回调接口,你必须决定是否为每个服务功能的一个特殊的回调接口或者是否你提供了大量的回调函数,一个回调接口。在后一种情况下,用于服务调用的API的所有回调的客户必须实现完整的回调接口虽然大部分方法体是空的。您可以解决此通过执行空机关存根,并让您的回调客户端从存根继承,但这是不可能的,如果已经从另外一个基类继承。也许你可以使用某种类型的动态代理回调(见<一href="http://developer.android.com/reference/java/lang/reflect/Proxy.html">http://developer.android.com/reference/java/lang/reflect/Proxy.html),但后来它变得非常复杂,我想使用另一种机制。
  • 客户端的回叫电话必须通过各种方法/组件进行传播,如果它不是由服务的呼叫者直接访问。
  • You have to switch to the main thread in order to do UI manipulations.
  • You can only have a 1-to-1 relationship. A 1-to-n relationship (observer pattern) is not realizable without further work. In this case I would prefer Android's Observer / Observable mechanism.
  • As you already said, you always have to check for null before invoking callback functions if the callback may be optional.
  • If your component should offer a kind of service API with different service functions and you do not want to have a callback interface with only a few generic callback functions, you have to decide whether you provide a special callback interface for each service function or whether you provide a single callback interface with a lot of callback functions. In the later case all callback clients used for service calls to your API have to implement the complete callback interface although the majority of the method bodies will be empty. You can work around this by implementing a stub with empty bodies and make your callback client inherit from that stub, but this is not possible if already inheriting from another base class. Maybe you can use some kind of dynamic proxy callback (see http://developer.android.com/reference/java/lang/reflect/Proxy.html), but then it gets really complex and I would think of using another mechanism.
  • The client for the callback calls has to be propagated through various methods/components if it is not directly accessible by the caller of the service.

对于一些分的BroadcastReceiver -approach:

Some points regarding the BroadcastReceiver-approach:

PRO

  • 您的组件之间实现松耦合。
  • 您可以有1到n的关系(包括1到0)。
  • 的onReceive()方法总是执行主线程上。
  • 您可以在您的整个应用程序通知组件,因此通信组件没有看到海誓山盟。
  • You achieve a loose coupling between your components.
  • You can have a 1-to-n relationship (including 1-to-0).
  • The onReceive() method is always executed on the main thread.
  • You can notify components in your entire application, so the communicating components do not have to "see" eachother.

魂斗罗

  • 这是一个非常通用的做法,所以编组和传输的数据unmarchalling的意图是一个额外的误差源。
  • 您必须让你的意图的行动唯一的(例如,通过prepending包的名称),如果你想消除的相关性与其他应用程序,因为他们原来的目的是为了应用程序之间做节目。
  • 您有管理的BroadcastReceiver登记和注销。如果你想这样做,在一个更​​舒适的方式,可以实现自定义进行注解的活动与应该注册的行为,并且确实实现基本活动类注册和注销与的IntentFilter S在其 onResume() RESP。 的onPause()的方法。
  • 正如你所说的,所发送的数据的意图的实施 Parcelable 界面,但此外,还有一个严格的大小限制,它会导致性能问题,如果你传送大量的数据与你的意图。请参阅<一href="http://$c$c.google.com/p/android/issues/detail?id=5878">http://$c$c.google.com/p/android/issues/detail?id=5878对于上的讨论。所以,如果你想发送的图像,例如你要存储这些临时的储存库,并发送相应的ID或URL,以从你的意图的接收器,访问图像删除从使用后的资源库。这将导致更多的问题,如果有多个接收器(时应图像从资源库中删除,谁应该这样做吗?)。
  • 如果你过度使用这种通报机制,你的应用程序的控制流可能会隐藏和调试,当你最终绘制图形与序列意图 s到明白了触发特定的错误,或者为什么这个通知链在某种程度上打破。
  • This is a very generic approach, so marshalling and unmarchalling of data transported by the Intent is an additional error source.
  • You have to make your Intent's actions unique (e.g. by prepending the package name) if you want to eliminate correlations with other apps, as their original purpose is to do broadcasts between applications.
  • You have to manage the BroadcastReceiver-registration and unregistration. If you want to do this in a more comfortable way, you can implement a custom annotation to annotate your Activity with the actions that should be registered and implement a base Activityclass that does registration and unregistration with IntentFilters in its onResume() resp. onPause()methods.
  • As you already said, the data that is sent with the Intent has to implement the Parcelable interface, but furthermore there is a strict size limitation and it will cause performance issues if you transport a large amount of data with your Intent. See http://code.google.com/p/android/issues/detail?id=5878 for a discussion on that. So if you want to send images for example you have to store them temporary in a repository and send a corresponding ID or URL to access the image from the receiver of your Intent that deletes it from the repository after usage. This leads to further problems if there are several receivers (when should the image be removed from the repository and who should do that?).
  • If you overuse this kind of notification mechanism the control flow of your application may get hidden and when debugging you end up drawing graphs with sequences of Intents to understand what has triggered a specific error or why this notification chain is broken at some point.

在我看来,即使是一个移动应用程序应该有至少2层的建筑群:UI层和核心层(业务逻辑等)。在一般情况下,长时间运行的任务都在自己的线程(也许通过的AsyncTask 执行或 HandlerThread 如果使用<$ C $一旦此任务已完成C> MessageQueue 多个)核心层和UI内应该更新。在一般以回调你实现你的组件之间的紧耦合,所以我会preFER只使用中的某一层,而不是跨层边界通信这种方法。对于用户界面 - 与核心层之间的消息广播我会使用的BroadcastReceiver -approach,让您从逻辑层分离的UI层。

In my opinion, even a mobile app should have an architecture base on at least 2 layers: the UI-layer and the core layer (with business logic, etc.). In general, long running tasks are executed in an own thread (maybe via AsyncTask or HandlerThread if using MessageQueues) inside the core layer and the UI should be updated once this task has been finished. In general with callbacks you achieve a tight coupling between your components, so I would prefer using this approach only within a layer and not for communication across layer boundaries. For message broadcasting between UI- and core-layer I would use the BroadcastReceiver-approach that lets you decouple your UI layer from the logic layer.

这篇关于安卓的BroadcastReceiver或简单的回调方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆