EventBus原理總結(jié)

使用上比較簡單,就是注冊和解注冊以及發(fā)送事件辩越,外加一個(gè)黏性事件。

注冊

注冊主要是將當(dāng)前Activity對象傳進(jìn)去信粮,然后拿到對應(yīng)的class黔攒;
反射拿到所有的方法,然后對方法進(jìn)行過濾强缘;需要有對應(yīng)的注解督惰,需要是public方法,需要是只有一個(gè)參數(shù)欺旧;
這中間入股需要追溯父類和接口姑丑,則需要去當(dāng)前類的父類中去找對應(yīng)的符合條件的方法,同時(shí)對參數(shù)的父類以及接口也有涉獵辞友。
組裝方法類栅哀,包括在什么線程執(zhí)行,優(yōu)先級等称龙;
拿到當(dāng)前類所有符合條件的組合方法后留拾,執(zhí)行訂閱;
在訂閱中鲫尊,存在一個(gè)全局MAP痴柔,就是按照類型參數(shù)為key,當(dāng)前類class和組合方法再組合的類組成的List作為value(一般接受事件會在多個(gè)Activity中都有涉獵)疫向,形成一個(gè)全局的大列表咳蔚,保存起來豪嚎。

如果在注冊之前有黏性事件發(fā)送,則在注冊后就立即執(zhí)行之前的黏性事件谈火。

發(fā)送事件

從大列表中侈询,根據(jù)參數(shù)類型找到對應(yīng)的再組合List,然后在指定的線程中反射執(zhí)行糯耍。

黏性事件發(fā)送就是在發(fā)送事件的基礎(chǔ)上增加一個(gè)List記錄一下扔字,這樣在別的Activity中注冊時(shí)會檢測是否有需要執(zhí)行的黏性事件,直接執(zhí)行温技,執(zhí)行完移除記錄革为。List中存儲的始終是未執(zhí)行的。

解注冊

沒什么好說的舵鳞,從對應(yīng)的列表中移除震檩。

索引

之前的操作都是在注冊時(shí)反射操作,于性能上有損耗蜓堕;索引是在編譯期提前生成代碼恳蹲。需要增阿基注解處理器,注解處理器去生成俩滥,使用規(guī)則就是在初始化時(shí)增加索引嘉蕾;索引里面描述方法組合信息,這樣就不用速反射查找了霜旧,提前自己查找好错忱,然后添加進(jìn)去,把反射的工作用手動替代了挂据。

從性能上來說是提升了一點(diǎn)以清,但是從代碼維護(hù)和編寫上來說,累崎逃。

事件傳遞性

接收事件的class

  • 當(dāng)前類中
    • 事件參數(shù)類型都會接收
    • 事件參數(shù)類型的父類也都會接收
  • 當(dāng)前類父類中
    • 事件參數(shù)類型都會接收
    • 事件參數(shù)類型的父類也都會接收

還有一個(gè)不太靠譜的東西掷倔,就是當(dāng)前類AA的父類A中,存在同名方法event,且方法參數(shù)類型都是發(fā)送類型个绍;這種情況下勒葱,最多有一個(gè),超過一個(gè)就報(bào)錯(cuò)巴柿。

當(dāng)前類AA凛虽,父類A;
事件XX广恢,父類X;
AA中的事件eventAA1(XX),eventAA2(XX);
A中的事件eventAA1(XX),eventAA2(XX);
發(fā)送事件post(XX)

上面父類A中有兩個(gè)同名方法凯旋,就掛了,最多允許一個(gè);XX換成X至非,也是如此钠署。
真不靠譜,有啥意義呢荒椭?


2021-11-24補(bǔ)充

幾個(gè)集合

private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
private final Map<Object, List<Class<?>>> typesBySubscriber;
private final Map<Class<?>, Object> stickyEvents;

一共四個(gè)集合踏幻;

第一個(gè)集合的用處和作用:

用處:
用于發(fā)射事件類型的繼承性,如果要考慮繼承性戳杀,會將事件類型的Class以及對應(yīng)的父類Class,接口Class一直往上追溯夭苗,組裝成一個(gè)Class列表作為value信卡,然后以該事件類型的Class作為key。

作用:
在發(fā)射對應(yīng)的事件時(shí)题造,如果考慮事件繼承傍菇,則會把該事件對應(yīng)的所有父類以及接口類Class都找出來,然后在另一個(gè)集合中(上面第二個(gè)集合)去查找已經(jīng)注冊過得“宿主”界赔,然后執(zhí)行丢习。

第二個(gè)集合的用處和作用

用處:
“宿主”里面會有起碼一個(gè)的注解事件方法,這里將注解事件方法拆分淮悼,拿到所有的信息(方法Method咐低,執(zhí)行線程,事件參數(shù)類型袜腥,優(yōu)先級见擦,黏性標(biāo)簽)組裝成一個(gè)方法信息承載類SubscriberMethod,然后再組裝一個(gè)“宿主-方法”信息承載類羹令,里面包括“宿主”和SubscriberMethod鲤屡,這個(gè)“宿主-方法”信息承載類就是Subscription;
一個(gè)事件類型可能會有多個(gè)“宿主”注冊福侈,這里以事件Class為key酒来,Subscription組成的List為value。

作用:

在注冊階段收集肪凛,一是可以防止重復(fù)注冊堰汉;而且在初測階段就根據(jù)優(yōu)先級排好了序;
再一個(gè)就是在時(shí)間發(fā)送時(shí)伟墙,根據(jù)事件Class找到所有注冊過的方法衡奥,然后去反射執(zhí)行。

延伸:

和第一個(gè)集合配合远荠,就是第一個(gè)集合找到父類以及父接口等所有可追溯的Class矮固,然后在這個(gè)集合中去查找對應(yīng)搜集的方法。

第三個(gè)集合的作用和用處

用處:

以“宿主”為key,宿主里面的所有注冊事件類型的Class組成的List為value档址。

作用:

在注冊時(shí)搜集盹兢。
因?yàn)槭且浴八拗鳌睘閗ey的,所以可以對外提供方法守伸,判斷該宿主是否已經(jīng)注冊绎秒;

在解注冊時(shí),是要釋放一個(gè)宿主尼摹,于是就根據(jù)當(dāng)前“宿主”找到所有注冊事件類型见芹;找到了事件的類型,就到了第一個(gè)和第二個(gè)集合以事件類型為key的主場蠢涝;第二個(gè)集合直接根據(jù)事件類型玄呛,找到對應(yīng)的“宿主-方法”信息承載體,直接移除和二;

第一個(gè)集合啥都沒做徘铝,為什么呢?因?yàn)闆]必要惯吕;首先解注冊時(shí)釋放的是“宿主”惕它,而不是一個(gè)事件類型,所以該“宿主”里面注冊的事件類型在別的地方可能也會用到废登;第二個(gè)就是這個(gè)事件類型對應(yīng)的列表是一個(gè)緩存淹魄,下次進(jìn)來或者別的頁面也存在該事件類型的地方還會復(fù)用。所以釋放意義不大堡距。

另外他的作用是在發(fā)射事件的時(shí)候體現(xiàn)出來揭北,他會遍歷事件類型的父類以及接口等往上追溯的Class,對應(yīng)的“宿主-方法”吏颖,然后去執(zhí)行搔体,但是查找需要第二個(gè)集合的幫忙,而第二個(gè)集合解注冊時(shí)已經(jīng)移除了半醉,所以也不會有事件去響應(yīng)疚俱。

第四個(gè)集合的作用和用處

用處:

用來手機(jī)黏性事件,事件參數(shù)Class為key缩多,事件參數(shù)為value呆奕。

作用:

發(fā)射的時(shí)候搜集。
在“黏性宿主”注冊時(shí)衬吆,去列表取出執(zhí)行梁钾。

如果黏性事件類型有子類,則子類也會響應(yīng)逊抡;但是這里不是自己去追溯子類姆泻,而是確實(shí)發(fā)射過子類的粘性事件并存儲在該列表中零酪。

上面那個(gè)子類做個(gè)解釋,他不是直接去響應(yīng)子類的方法拇勃;比如發(fā)射一個(gè)子類事件和父類事件四苇,在”宿主“初始化注冊時(shí),如果注冊了父類方法方咆,則兩個(gè)黏性事件都會在父類方法中標(biāo)執(zhí)行月腋。
發(fā)送一個(gè)父類型,一個(gè)子類型瓣赂,最終父事件中會執(zhí)行父類型和子類型榆骚,子事件中只會執(zhí)行子事件

所以黏性事件的這種機(jī)制還蠻奇怪的。

延伸:

并沒有看到黏性事件的移除煌集,也就意味著妓肢,這個(gè)黏性事件在執(zhí)行后仍然會再次執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市牙勘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌所禀,老刑警劉巖方面,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異色徘,居然都是意外死亡恭金,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進(jìn)店門褂策,熙熙樓的掌柜王于貴愁眉苦臉地迎上來横腿,“玉大人,你說我怎么就攤上這事斤寂」⒑福” “怎么了?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵遍搞,是天一觀的道長罗侯。 經(jīng)常有香客問我,道長溪猿,這世上最難降的妖魔是什么钩杰? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮诊县,結(jié)果婚禮上讲弄,老公的妹妹穿的比我還像新娘。我一直安慰自己依痊,他們只是感情好避除,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般驹饺。 火紅的嫁衣襯著肌膚如雪钳枕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天赏壹,我揣著相機(jī)與錄音鱼炒,去河邊找鬼。 笑死蝌借,一個(gè)胖子當(dāng)著我的面吹牛昔瞧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播菩佑,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼自晰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了稍坯?” 一聲冷哼從身側(cè)響起酬荞,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞧哟,沒想到半個(gè)月后混巧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勤揩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年咧党,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陨亡。...
    茶點(diǎn)故事閱讀 40,926評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡傍衡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出负蠕,到底是詐尸還是另有隱情蛙埂,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布遮糖,位于F島的核電站箱残,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏止吁。R本人自食惡果不足惜被辑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望敬惦。 院中可真熱鬧盼理,春花似錦、人聲如沸俄删。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至臊诊,卻和暖如春鸽粉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抓艳。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工触机, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玷或。 一個(gè)月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓儡首,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偏友。 傳聞我的和親對象是個(gè)殘疾皇子蔬胯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 小知識 觀察者模式 :定義對象間一種一對多的依賴關(guān)系,使得每當(dāng)一個(gè)對象改變狀態(tài)位他,則所有依賴它的對象都會得到通知并自...
    方言方言閱讀 250評論 0 0
  • EventBus作用 事件總線用于觀察者模式氛濒,用于通知使用,需要注冊鹅髓,和解注冊舞竿,訂閱要執(zhí)行的方法,然后post發(fā)送...
    楊殿生閱讀 1,397評論 0 0
  • EventBus是一個(gè)Android開源庫迈勋,其使用發(fā)布/訂閱模式炬灭,以提供代碼間的松耦合醋粟。EventBus使用中央通...
    壯少Bryant閱讀 663評論 0 4
  • 轉(zhuǎn)自Android面試之EventBus原理分析[https://zhuanlan.zhihu.com/p/778...
    Ella_Eric閱讀 247評論 0 2
  • 現(xiàn)實(shí)開發(fā)中用到的框架為了方便更好的理解加深記憶靡菇,歸納如下: 在開發(fā)中使用eventbus主要是為了進(jìn)行傳值和傳...
    簡書不簡單iiii閱讀 1,493評論 1 6