【问题标题】:EventBus vs Callbacks, which to use when?EventBus vs Callbacks,什么时候使用?
【发布时间】:2015-05-14 12:42:20
【问题描述】:

我有很多活动会引发后台任务;活动将自己传递为已实现侦听器回调,以便后台任务可以在活动上引发事件。反过来,活动可以在 UI 上显示一些内容,以指示后台活动通过或失败。

或者,我可以使用EventBus,让 Activity 将自己注册为侦听器/订阅者。我可以让后台任务在 EventBus 上引发一个事件,并且监听它的 Activity 可以处理它。

一个比另一个有什么优势?您什么时候会使用其中一种? (代码清洁度?性能?注意事项?)


跟进 - 我确实最终使用了 EventBus。代码绝对干净多了,而且到处都没有回调。 IDE(IntelliJ)认为onEvent方法没有被使用,所以我创建了一个注解

@Target({ElementType.METHOD})
public @interface EventBusHook {}

并将它放在我的 onEvent 方法上。然后 Alt+单击它并要求 IntelliJ 不要将其视为未使用。

@EventBusHook
public void onEvent(MyEventType myEventType){

【问题讨论】:

  • 我会使用本地绑定服务来启动任务,并使用绑定到该服务并创建“绑定”来发送结果的活动

标签: android callback event-bus


【解决方案1】:

我会选择EventBus,因为它是松散耦合和更简洁的代码。此外,使用诸如 Greenrobot 之类的 EventBus 会自动为我完成所有样板,并允许我直接从 Activity 生命周期方法(onStart 和 onDestroy|onStop)注册和注销观察者,这一点很棒。实现回调并仍然设法控制这些回调的 Activity 生命周期管理是一个不必要的麻烦,并且涉及许多不必要的样板。

另外,apparently all garbage collectors think weak reference is great-Event 总线为您的观察者和组件提供了这一点。它是Observer pattern 的基础。

【讨论】:

    【解决方案2】:

    您应该检查您的事件在语义视图上是否是全局唯一的。订阅者是否对该事件感兴趣。如果不是,他不应该订阅。

    如果您确实具有发布者-订阅者关系,事件总线机制是正确的。事件必须完全独立于接收者。

    因此,出于任何责任原因(“即使我已注册,我也不对该事件负责”)放弃该事件的订阅者是一个强有力的指标,表明使用 Event-Bus 是错误的。那么你应该考虑使用专门的监听器。

    【讨论】:

      【解决方案3】:

      我不同意@nnuneoi 的回答。

      事件总线只有一个优点:它允许在“不知道”彼此存在的组件之间进行通信。

      还有几个缺点:

      1. 组件因依赖事件总线和特定事件类型而变得松散耦合
      2. 上面 #1 中描述的耦合不强
      3. 上述 #1 中描述的耦合不明显
      4. 事件总线引入了简单回调的性能开销
      5. 如果事件总线持有对订阅者的强引用(例如 GreenRobot's EventBus 就是这种情况),那么未注册的订阅者将导致内存泄漏

      鉴于所有这些缺点,简单的回调应该是默认的实现选择。

      仅当不需要或难以实现直接耦合时才应使用事件总线。例如:

      1. 将事件从Service 发送到Activity
      2. 在独立Fragments之间交换事件
      3. 应用程序范围的事件(例如用户登录/注销)

      如果通信组件已经“知道”彼此的存在,则它们无需通过事件总线进行通信。

      【讨论】:

      • 组件将松散耦合的论点足以证明不使用 EventBus 进行简单的 Activity / Fragment 通信。由于 Fragment 无论如何都附加到 Activity。
      • @MuratK.,不完全是。 Fragment 附加到 Activity,但为了能够从特定 Fragment 与特定 Activity 进行通信,片段将需要耦合到该特定 Activity 类(或 Activity 实现的某些接口)。这是一种更强的耦合类型,它还需要转换从getActivity() 调用返回的引用。因此,在某些情况下,只使用 EvenBus 会更干净。在 Fragment 到 Fragment 的通信(通过 Activity)的情况下,耦合会更加紧密,这使得 EventBus 更加有益。
      • @Vasiliy 我有一个片段和后台服务。服务 - 数据源,片段 - 订阅者(显示数据)。我使用绿色 EventBus。如果 Activity 被杀死,Service 会失去其订阅者,但会继续工作。这种情况下会不会有内存泄漏?
      • @tim4dev,只要注册到 EventBus 的 Activity 和 Fragment 在其 onStop() 方法中未注册 - 就不会有内存泄漏。即使没有订阅者,服务也可能继续发布事件。顺便说一句,在像你这样的情况下,我发现粘性事件非常有用。
      【解决方案4】:

      使用 EventBus 的好处:

      • 您的代码看起来会更干净
      • 您的代码将变得更加模块化,这将允许您轻松地为您的代码创建测试用例
      • 避免因锁定对象且不允许垃圾收集器清理对象的错误对象引用导致内存泄漏
      • 一次可以有多个接收器,这很像广播
      • 将多个接口简化为一个 EventBus
      • 在接口类中,您需要覆盖被继承的类中的每一个方法。使用 EventBus,您可以只监听您真正想要的事件

      但不好的部分是你可能对函数声明有点头疼,因为 IDE 无法帮助你自动完成。

      我的建议是,如果您发现必须创建自定义侦听器,请考虑使用 EventBus,它可能是您的大多数(如果不是全部)需求/案例的更好选择。

      不管怎样,这都是你的选择=)

      【讨论】:

      • 谢谢,因为你的前 3 点,我一直倾向于 EventBus。我会尝试一下,看看它在 IntelliJ 中的表现如何。
      猜你喜欢
      • 1970-01-01
      • 2016-09-09
      • 2018-10-28
      • 2021-02-01
      • 1970-01-01
      • 2015-10-27
      • 2011-08-17
      • 2013-09-14
      • 1970-01-01
      相关资源
      最近更新 更多