EventBus (發(fā)布者和訂閱者)
前言
小項(xiàng)目頁面間、線程間薄腻、模塊間收捣,通信一般使用:公共變量、Intent庵楷、Handler罢艾、Broadcast磕瓷,接口等等贺纲。婆誓。
當(dāng)項(xiàng)目越來越復(fù)雜時(shí)铭段,使用這些通信方式之后啊胶,代碼量大茫打,邏輯錯終復(fù)雜累贤,高度耦合狱杰。為了解決這個大問題差凹,然后就誕生了這個框架期奔。
官網(wǎng)示例調(diào)用代碼:
EventBus in 3 steps
-
Define events:
public static class MessageEvent { /* Additional fields if needed */ }
-
Prepare subscribers: Declare and annotate your subscribing method, optionally specify a thread mode:
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) {/* Do something */};
Register and unregister your subscriber. For example on Android, activities and fragments should usually register according to their life cycle:
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); }
-
Post events:
EventBus.getDefault().post(new MessageEvent());
自定義Event事件
訂閱者接收消息注冊:EventBus.getDefault().register()(一般在onCreate中注冊)
訂閱者取消訂閱注冊:EventBus.getDefault().unregister();(一般在onDestory中解除注冊)
發(fā)布者發(fā)送消息:EventBus.getDefault().post(event)
訂閱者接收消息:1侧馅、注解 2、主線程 3呐萌、event中取消息
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent evnt){}
圖解:
擴(kuò)展:
onEvent:發(fā)送者在哪個線程發(fā)送的馁痴,該方法也在哪個線程中處理事件
onEventMainThread:不管發(fā)送者在哪個線程發(fā)送的,該方法都會在主線程中處理事件
onEventBackgroundThread:如果發(fā)送者是在子線程發(fā)送的肺孤,那么該方法也在同一個子線程處理事件罗晕,如果發(fā)送者是在主線程,那么該方法在一個線程池中處理事件
onEventAsync:不管發(fā)送者在哪個線程發(fā)送的赠堵,該方法都在線程池中執(zhí)行
原理:
先從注冊開始看攀例,
1、EventBus.getDefault().register(this);將Activity.this傳遞進(jìn)EventBus當(dāng)中顾腊,里面通過反射粤铭,獲取到包含@Subscribe 注解的函數(shù),
2杂靶、篩選onEvent開頭的方法梆惯,獲取方法的權(quán)限修飾符,必須是public吗垮,然后獲取函數(shù)所需參數(shù)數(shù)組垛吗,
3、通過把方法名烁登,方法形參怯屉,線程模型封裝成一個SubscriberMethod添加進(jìn)集合里,
3饵沧、然后遍歷集合中當(dāng)前訂閱者的所有訂閱方法锨络,通過訂閱方法參數(shù)的字節(jié)碼,創(chuàng)建訂閱者狼牺,優(yōu)先級處理羡儿,事件類型處理
再看Post:
1、獲取當(dāng)前線程的隊(duì)列是钥,將event添加到隊(duì)列里掠归;
2、通過event拿到事件的字節(jié)碼悄泥,注意event是支持繼承的虏冻,會獲取到事件的父類和接口的字節(jié)碼到集合中;
3弹囚、然后通過該事件字節(jié)碼獲取所有的訂閱者厨相。
4、根據(jù)不同的線程模型調(diào)用不同的方法:
通過反射調(diào)用訂閱者訂閱方法
handler發(fā)送消息
在線程池發(fā)送消息(包含異步或者后臺兩種)