瞎扯
干android有段時間的人,應(yīng)該都用過eventbus,rxbus之類的
那么,這個東西是怎么實現(xiàn)通信的.
其實要說原理的話,很簡單....
生產(chǎn)者/消費(fèi)者模式
說到生產(chǎn)者,消費(fèi)者.
可以想到handler.looper.也是生產(chǎn)者/消費(fèi)者,
這個是同步的.所以looper是個阻塞的死循環(huán)
就好比你去飯店排隊點(diǎn)餐.需要排隊
你排隊點(diǎn)餐就是生產(chǎn)者
點(diǎn)餐員就是消費(fèi)者
eventbus也是生產(chǎn)者/消費(fèi)者.
但是eventbus不需要同步.
這個是異步的,因為每個事件都有單獨(dú)的消費(fèi)者.
post =>register
register的回調(diào)是消費(fèi)者
post的event消息就是生產(chǎn)者.
實現(xiàn)bus的幾個點(diǎn)
一個單例
我們需要一個單例,里面有一個Map集合,來保存type.回調(diào),
但是一個type,可能有多種狀態(tài),所以再嵌套一層code.當(dāng)然只要你愿意,還可以在嵌套
不過我覺得2層已經(jīng)足夠了,
public class Event {
//保存注冊的事件
private static final Map<Class, Map<Object, Callback>> map = new HashMap<>();
}
register
就是把Type,和回調(diào),保存到集合里
//注冊事件,消費(fèi)者
public static void register(Class type, Object code, Callback callback) {
Map<Object, Callback> callbackMap = map.get(type);
if (callbackMap == null) {//判斷這個type,有沒有被注冊過
callbackMap = new HashMap<>();
callbackMap.put(code, callback);//添加code,與回調(diào)
map.put(type, callbackMap);
} else {
callbackMap.put(code, callback);
}
}
Post方法
post方法,實際上實現(xiàn)就是,
去單例的集合里面,找出對應(yīng)的type.
然后取出回調(diào).把post傳進(jìn)來的內(nèi)容傳到回調(diào)里.
//發(fā)生消息,event,生產(chǎn)者
public static void post(Class type, Object code, Object action) {
Map<Object, Callback> objectCallbackMap = map.get(type);//判斷這個type有沒有注冊
if (objectCallbackMap == null) {
return;
}
Callback callback = objectCallbackMap.get(code);//獲取對應(yīng)code的回調(diào)
if (callback != null) {
callback.call(action);
}
}
全部代碼
public class Event {
//保存注冊的事件
private static final Map<Class, Map<Object, Callback>> map = new HashMap<>();
//發(fā)送event消息,生產(chǎn)者
public static void post(Class type, Object code, Object action) {
Map<Object, Callback> objectCallbackMap = map.get(type);//判斷這個type有沒有注冊
if (objectCallbackMap == null) {
return;
}
Callback callback = objectCallbackMap.get(code);//獲取對應(yīng)code的回調(diào)
if (callback != null) {
callback.call(action);
}
}
//注冊事件,回調(diào)就是消費(fèi)者
public static void register(Class type, Object code, Callback callback) {
Map<Object, Callback> callbackMap = map.get(type);
if (callbackMap == null) {//判斷這個type,有沒有被注冊過
callbackMap = new HashMap<>();
callbackMap.put(code, callback);//添加code,與回調(diào)
map.put(type, callbackMap);
} else {
callbackMap.put(code, callback);
}
}
/**
* 事件回調(diào)
*/
public interface Callback {
void call(Object o);
}
}
不扯設(shè)計,實現(xiàn)總結(jié)
其實通俗點(diǎn)講就是:
1.一個單例保存Type和回調(diào)
2.因為是單例,所以其保存的相當(dāng)于全局可見可用
3.所以在取消注冊前(也就是從單例中刪除),相當(dāng)于是全局的,也就會一直存在內(nèi)存中
4.然后就能隨時訪問里面的回調(diào).達(dá)到跨域通信的目的.
一句話:想了一個辦法,能直接訪問需要的內(nèi)存中的某個對象.
至于注解啥的啊,就像昨天寫的,只是加個標(biāo)記方便擴(kuò)展,生成判斷代碼,節(jié)省代碼用的.
交流群:493180098,這是個很少吹水,交流學(xué)習(xí)的群.
APP開發(fā)維護(hù)咨詢?nèi)?: 492685472 ,承接APP迭代.開發(fā)維護(hù).咨詢業(yè)務(wù),付費(fèi)快速解決問題.