Otto小巧的事件总线
Otto,不是KSG的中单,是Square在2015年发布的事件总线通信库,作者是大名鼎鼎的JakeWharton。代码行数550行(注释420行)只有EventBus的1/3,经过多年的打磨已于2019年封存不再维护。它仍然值得开发者学习。
Otto是一个事件总线,用于应用程序的不同组件之间进行有效的通信,用来降低程序之间的耦合性。Bus构造没有使用建造者模式,直接使用Bus构造函数初始化实例:
//使用默认的DEFAULT_IDENTIFIER名称
Bus bus = new Bus();
或指定bus的名称:
//指定bus的名称
Bus bus = new Bus("Quibbler");
以便调试打印区别不同的Bus总线对象(正常情况全局一个单例即可):
@Override public String toString() {
return "[Bus \"" + identifier + "\"]";
}
与EventBus不同的是,Otto中默认Bus中的事件回调是在主线程ThreadEnforcer.MAIN,也可以指定为任意线程ThreadEnforcer.ANY,或者实现ThreadEnforcer接口自定义,在构造的时候指定。而EventBus可以对每个注册的事件方法单独指定运行策略,详见EventBus源码分析(二):事件分发及处理。
Bus bus = new Bus(ThreadEnforcer.ANY);
Otto同样使用观察者设计模式,主要对象:发布者、订阅者、事件。先定义一个事件:
public static class Event {
//something
}
在订阅者内定义方法,并使用@Subscribe注解该方法,方法参数指定需要监听的事件:
@Subscribe
public void onEvent(Event event) {
//todo
}
使用register()方法注册事件订阅者:
bus.register(suscriber);
在应用同进程内通过post()方法将事件发布消息给订阅者,实现解耦:
bus.post(new Event());
一定别忘记unregister()反注册订阅者,Android中内存泄漏一部分原因是因为注册后没有反注册引起:
bus.unregister(suscriber);
Otto就是这么简单直接,仅定义暴露三个公有方法:register()、post()、unregister(),没有其它多余眼花缭乱的方法。
一个优秀的开源库应当尽可能暴露少的接口,将大部分操作封装起来,使用起来力求简洁高效。接下来学习Otto内部的实现,如何用550行代码实现事件总线。
精彩的人生需要浪漫、无畏和勇气。