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這個方法)
- 消息分組/定向發送(指定消息的接受者)
- ...
就得加上 反射 / 自定義注解 等看起來高大上的東西了....