EventBus vs Callbacks,什么时候使用哪个?
EventBus vs Callbacks, which to use when?
我有很多引发后台任务的活动; Activities 将自己传递为已实现侦听器回调,以便后台任务可以在 Activities 上引发事件。反过来,活动可以在 UI 上显示一些内容,以指示背景 activity 通过或失败。
或者,我可以使用 EventBus,其中我让 Activity 将自己注册为 listener/subscriber。我可以让一个后台任务在 EventBus 上引发一个事件,监听它的 Activity 可以处理它。
一个比另一个有什么优势?你什么时候会用一个而不是另一个? (代码整洁度?性能?注意事项?)
跟进 - 我最终使用了 EventBus。代码绝对更简洁,并且没有回调随处可见。 IDE (IntelliJ) 认为 onEvent
方法未被使用,所以我创建了一个注释
@Target({ElementType.METHOD})
public @interface EventBusHook {}
并将其置于我的 onEvent
方法之上。然后 Alt+Clicked 并要求 IntelliJ 不要将其视为未使用。
@EventBusHook
public void onEvent(MyEventType myEventType){
使用 EventBus 的好处:
- 您的代码看起来会更干净
- 您的代码将变得更加模块化,这将使您可以轻松地为您的代码创建测试用例
- 避免锁定对象并且不允许垃圾收集器清理它的错误对象引用造成内存泄漏
- 一次可以有多个接收器,这很像广播
- 将多个接口简化为一个,EventBus
- 在接口 class 中,您需要重写 class 中继承的每个方法。使用 EventBus,您可以只监听您真正想要的事件
但不好的是函数声明可能会让您更头疼,因为 IDE 无法帮助您自动完成。
我的建议是,如果您发现必须创建自定义侦听器,那么请考虑 EventBus,对于您的大部分(如果不是全部)requirements/cases,它可能是更好的选择。
反正都是自己的选择=)
我不同意@nnuneoi 的回答。
事件总线只有一个优势:它允许“不知道”彼此存在的组件之间进行通信。
并且有几个缺点:
- 组件因对事件总线和特定事件类型的依赖而变得松散耦合
- 上面 #1 中描述的耦合不强
- 上面 #1 中描述的耦合不明显
- 事件总线相对于简单的回调引入了性能开销
- 如果事件总线持有对订阅者的强引用(例如 GreenRobot's EventBus 的情况),那么未注册的订阅者将导致内存泄漏
考虑到所有这些缺点,简单的回调应该是默认的实现选择。
仅当不需要直接耦合或难以实现时才应使用事件总线。例如:
- 正在将事件从
Service
发送到 Activity
- 在独立
Fragments
之间交换事件
- 应用程序范围内的事件(例如用户 login/logout)
如果通信组件已经“知道”彼此的存在,则它们不需要通过事件总线进行通信。
您应该检查您的事件在语义视图中是否是全局唯一的。订阅者是否对该事件感兴趣。如果不是,他不应该订阅。
如果你真的有发布者-订阅者关系,事件总线机制是正确的。该事件必须完全独立于接收者。
因此,出于任何责任原因丢弃事件的订阅者 ("I am not responsible the event even if I am registered") 强烈表明使用事件总线是错误的。那么你应该考虑使用专门的监听器。
我会选择 EventBus,因为耦合松散且代码更简洁。此外,使用诸如 Greenrobot 之类的 EventBus 会自动为我完成所有样板,并允许我直接从 Activity 生命周期方法(onStart 和 onDestroy|onStop)注册和注销观察者这一事实非常棒。实施回调并仍然设法控制这些回调的 Activity 生命周期管理是一个不必要的麻烦,并且涉及许多不必要的样板文件。
此外,apparently all garbage collectors think weak reference is great-Event bus gives your observers and components exactly that. Its the basis of the Observer pattern。
我有很多引发后台任务的活动; Activities 将自己传递为已实现侦听器回调,以便后台任务可以在 Activities 上引发事件。反过来,活动可以在 UI 上显示一些内容,以指示背景 activity 通过或失败。
或者,我可以使用 EventBus,其中我让 Activity 将自己注册为 listener/subscriber。我可以让一个后台任务在 EventBus 上引发一个事件,监听它的 Activity 可以处理它。
一个比另一个有什么优势?你什么时候会用一个而不是另一个? (代码整洁度?性能?注意事项?)
跟进 - 我最终使用了 EventBus。代码绝对更简洁,并且没有回调随处可见。 IDE (IntelliJ) 认为 onEvent
方法未被使用,所以我创建了一个注释
@Target({ElementType.METHOD})
public @interface EventBusHook {}
并将其置于我的 onEvent
方法之上。然后 Alt+Clicked 并要求 IntelliJ 不要将其视为未使用。
@EventBusHook
public void onEvent(MyEventType myEventType){
使用 EventBus 的好处:
- 您的代码看起来会更干净
- 您的代码将变得更加模块化,这将使您可以轻松地为您的代码创建测试用例
- 避免锁定对象并且不允许垃圾收集器清理它的错误对象引用造成内存泄漏
- 一次可以有多个接收器,这很像广播
- 将多个接口简化为一个,EventBus
- 在接口 class 中,您需要重写 class 中继承的每个方法。使用 EventBus,您可以只监听您真正想要的事件
但不好的是函数声明可能会让您更头疼,因为 IDE 无法帮助您自动完成。
我的建议是,如果您发现必须创建自定义侦听器,那么请考虑 EventBus,对于您的大部分(如果不是全部)requirements/cases,它可能是更好的选择。
反正都是自己的选择=)
我不同意@nnuneoi 的回答。
事件总线只有一个优势:它允许“不知道”彼此存在的组件之间进行通信。
并且有几个缺点:
- 组件因对事件总线和特定事件类型的依赖而变得松散耦合
- 上面 #1 中描述的耦合不强
- 上面 #1 中描述的耦合不明显
- 事件总线相对于简单的回调引入了性能开销
- 如果事件总线持有对订阅者的强引用(例如 GreenRobot's EventBus 的情况),那么未注册的订阅者将导致内存泄漏
考虑到所有这些缺点,简单的回调应该是默认的实现选择。
仅当不需要直接耦合或难以实现时才应使用事件总线。例如:
- 正在将事件从
Service
发送到Activity
- 在独立
Fragments
之间交换事件
- 应用程序范围内的事件(例如用户 login/logout)
如果通信组件已经“知道”彼此的存在,则它们不需要通过事件总线进行通信。
您应该检查您的事件在语义视图中是否是全局唯一的。订阅者是否对该事件感兴趣。如果不是,他不应该订阅。
如果你真的有发布者-订阅者关系,事件总线机制是正确的。该事件必须完全独立于接收者。
因此,出于任何责任原因丢弃事件的订阅者 ("I am not responsible the event even if I am registered") 强烈表明使用事件总线是错误的。那么你应该考虑使用专门的监听器。
我会选择 EventBus,因为耦合松散且代码更简洁。此外,使用诸如 Greenrobot 之类的 EventBus 会自动为我完成所有样板,并允许我直接从 Activity 生命周期方法(onStart 和 onDestroy|onStop)注册和注销观察者这一事实非常棒。实施回调并仍然设法控制这些回调的 Activity 生命周期管理是一个不必要的麻烦,并且涉及许多不必要的样板文件。
此外,apparently all garbage collectors think weak reference is great-Event bus gives your observers and components exactly that. Its the basis of the Observer pattern。