ps.本篇不說源碼, 只介紹原理. 源碼很少, 可以自己去詳細(xì)觀摩...
引言
首先介紹下 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.
---- 以上摘自官方文檔
簡言之就是很牛叉的工具, 牛到: 既能降低代碼各個(gè)模塊間的耦合, 又能保證模塊之間高效通信.
(本篇基于版本com.squareup:otto:1.3.8
)
那么內(nèi)部是怎么實(shí)現(xiàn)的呢?
先說說模塊間通信這件事兒
通常來講, 兩個(gè)類或者兩個(gè)模塊之間如何通信呢?
以Activity 和 Fragment的通信為例, 其實(shí)就是相互持有對象, 對象再調(diào)用對方的方法. (Fragment 在Activity 中創(chuàng)建, 因此 Activity持有 Fragment的對象; Fragment寄生于Activity 中, 通過getActivity()拿到對象)
這種最基本的通信方式可用但并不優(yōu)雅, 耦合性太高.
怎么解耦? 當(dāng)然需要找個(gè)"中介".
我們暫且拋開" 注解 , 反射 , 緩存, 以及其他附加功能 "不談, 先實(shí)現(xiàn)一個(gè)最簡單的 較低耦合的通信模塊.
簡單實(shí)現(xiàn)
public class Sender {
public void send() {
Phone.getDefault().post(new Msg("這是消息內(nèi)容!"));
}
}
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<>();
/**
* 在通訊錄里添加聯(lián)系人
* @param target
*/
public void register(Receiver target){
if (!contacts.contains(target)) {
contacts.add(target);
}
}
/**
* 移除通訊錄中的某個(gè)聯(lián)系人
* @param target
*/
public void unregister(Receiver target){
contacts.remove(target);
}
/**
* 給通訊錄里的人群發(fā)消息
* @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);
}
}
以上便是一個(gè)簡化版的EventBus, 消息的發(fā)送者 和 接受者 兩個(gè)模塊之間幾乎沒有耦合, 同時(shí)又能借助手機(jī)這個(gè)中介實(shí)現(xiàn)通信.
是不是超級(jí)簡單! 本質(zhì)上就是構(gòu)造一個(gè)全局對象(Phone), 利用這個(gè)共享的全局對象進(jìn)行數(shù)據(jù)傳遞. 對, otto 就是這個(gè)原理. 至于其他額外的擴(kuò)展需求, 譬如:
- 自定義消息格式(不局限與Msg這個(gè)類)
- 自定義接收消息的方法名(不局限于onReceive這個(gè)方法)
- 消息分組/定向發(fā)送(指定消息的接受者)
- ...
就得加上 反射 / 自定義注解 等看起來高大上的東西了....