该不该使用EventBus
EventBus 虽然步入暮年,逐渐被RxJava替代,但是EventBus的强大解耦能力,使它任然有很高的人气,在开源项目中还是会经常看到。在代码设计阶段,有这么一个库在手边放着,很难保持不被诱惑过去。于是项目里,遍地都是post,subscribe,当有一天要调试一个Event相关的问题时,才发现,藏在各个角落里的subscriber是一场噩梦。
本文主要讨论一个问题:
EventBus,怎么取舍,何时用,何时不用?
pros
-
代码整洁,干净,不用写n多On**Listener了,也不用为了监听某一个事件,还要写n个空实现
public interface DialogInterface {
interface OnCancelListener {
public void onCancel(DialogInterface dialog);
}
interface OnDismissListener {
public void onDismiss(DialogInterface dialog);
}
interface OnShowListener {
public void onShow(DialogInterface dialog);
}
interface OnClickListener {
public void onClick(DialogInterface dialog, int which);
}
}public static interface AnimationListener {
void onAnimationStart(Animation animation);
void onAnimationEnd(Animation animation);
void onAnimationRepeat(Animation animation);
}
-
代码模块解耦程度高,事件触发容易,方便测试
-
不易发生内存泄露*,而Listener持有Act、Context实例是最常见的泄露case。
-
天生的一对多广播特性
cons
-
对特定的Event类的依赖,导致模块间并不是完全解耦,而这个耦合又不像Listener那么强而明显。导致IDE无法给你关于poster和reciver之间跳转的任何提示帮助。
-
相比Callback Listener,EventBus更多的依赖注解,反射,会牺牲一部分性能。
-
必须配合生命周期register和unregister,否则也会导致内存泄露
-
调试困难,当Event多起来,代码栈之间的跳转,会让人的大脑stackoverflow。
总结
大部分情况下,Callback Listener已经能满足,比如:在互相知晓内部实现的组件之间通信时,用listener就够了;
EventBus属于杀手锏级的武器。在设计时,不要因为使用方便,就轻易的将事件调用全改为EventBus。
当然遇到遇到下面的case时用EventBus确实很给力。
- 可能需要写跨Activity、Fragment的Listener时
- 两个互相独立的模块之间通信,比如登录模块和其他别的任何模块之间用EventBus
Author: deskid
Link: https://deskid.github.io/2017/05/26/EventBus不是银弹/
License: 知识共享署名-非商业性使用 4.0 国际许可协议