ps.本篇不说源码, 只介绍原理. 源码很少, 可以自己去详细观摩...
引言
首先介绍下 otto,
An enhanced Guava-based event bus with emphasis on Android support.
Otto is an event bus designed to decouple different parts of your application while still allowing them to communicate efficiently.
---- 以上摘自官方文档
简言之就是很牛叉的工具, 牛到: 既能降低代码各个模块间的耦合, 又能保证模块之间高效通信.
(本篇基于版本com.squareup:otto:1.3.8
)
那么内部是怎么实现的呢?
先说说模块间通信这件事儿
通常来讲, 两个类或者两个模块之间如何通信呢?
以Activity 和 Fragment的通信为例, 其实就是相互持有对象, 对象再调用对方的方法. (Fragment 在Activity 中创建, 因此 Activity持有 Fragment的对象; Fragment寄生于Activity 中, 通过getActivity()拿到对象)
这种最基本的通信方式可用但并不优雅, 耦合性太高.
怎么解耦? 当然需要找个"中介".
我们暂且抛开" 注解 , 反射 , 缓存, 以及其他附加功能 "不谈, 先实现一个最简单的 较低耦合的通信模块.
简单实现
public class Sender {
public void send() {
Phone.getDefault().post(new Msg("这是消息内容!"));
}
}
public class Receiver {
public void onReceive(Msg msg) {
if (msg != null)
System.out.println("收到消息: " + msg.getContent());
}
}
public class Phone {
private static Phone sInstance = new Phone();
public static Phone getDefault(){
return sInstance;
}
/**
* 通讯录
*/
private List<Receiver> contacts = new ArrayList<>();
/**
* 在通讯录里添加联系人
* @param target
*/
public void register(Receiver target){
if (!contacts.contains(target)) {
contacts.add(target);
}
}
/**
* 移除通讯录中的某个联系人
* @param target
*/
public void unregister(Receiver target){
contacts.remove(target);
}
/**
* 给通讯录里的人群发消息
* @param msg
*/
public void post(Msg msg) {
for (Receiver receiver : contacts) {
receiver.onReceive(msg);
}
}
}
public class Main {
public static void main(String[] args){
Receiver receiver = new Receiver();
Phone.getDefault().register(receiver);
new Sender().send();
Phone.getDefault().unregister(receiver);
}
}
以上便是一个简化版的EventBus, 消息的发送者 和 接受者 两个模块之间几乎没有耦合, 同时又能借助手机这个中介实现通信.
是不是超级简单! 本质上就是构造一个全局对象(Phone), 利用这个共享的全局对象进行数据传递. 对, otto 就是这个原理. 至于其他额外的扩展需求, 譬如:
- 自定义消息格式(不局限与Msg这个类)
- 自定义接收消息的方法名(不局限于onReceive这个方法)
- 消息分组/定向发送(指定消息的接受者)
- ...
就得加上 反射 / 自定义注解 等看起来高大上的东西了....