Android?EventBus粘性事件實現(xiàn)機制探究
眾所周知,EventBus是支持粘性事件的,即可以先發(fā)送粘性事件,然后再注冊,代碼如下:
- 粘性事件觀察者
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) fun registerEventBus(o: Any) { }
- 發(fā)送粘性事件
EventBus.getDefault().postSticky(Any())
- 注冊EventBus
EventBus.getDefault().register(this)
接下來我們就來探究下EventBus的粘性事件是如何實現(xiàn)的。
postSticky()內(nèi)部機制
- 如果是發(fā)送的粘性事件,會添加到
stickyEvents
中,看下這個屬性的實現(xiàn):
可以看到這個屬性是一個Map集合,其中key為事件類型的class對象,value為對應的事件類型。
- 繼續(xù)看下
post(Event)
方法:
首先將這個粘性事件添加到
PostingThreadState
(線程私有)的eventQueue
集合中通過
isMainThread
方法判斷當前是否為主線程,最終會調(diào)用到我們熟悉的Looper.getMainLooper() == Looper.myLooper()
進行判斷循環(huán)遍歷
eventQueue
隊列,不斷的取出集合元素進行分發(fā),看下postSinleEvent()
方法如何實現(xiàn):
如果
eventInheritance
為true,會查找當前發(fā)送的粘性事件類型的父類型,并返回查找到的集合接下來就會調(diào)用
postSingleEventForEventType()
方法來進行最終粘性事件的分發(fā),即通知通過@Subscribe
注解注冊的粘性事件觀察者,看下具體實現(xiàn):
- 調(diào)用
subscriptionsByEventType
獲取注冊該事件類型的所有訂閱方法,但是由于這個時候我們是先發(fā)送的粘性事件再注冊EventBus
,而subscriptionsByEventType
中集合元素的填充實在注冊EventBus
發(fā)生的,所以通過subscriptionsByEventType
獲取到的subscriptions
將是null的,所以接下來肯定不會走下面的if代碼塊中的邏輯了。
postSticky()小結(jié)
上面這么多代碼邏輯,其實只干了一件事,就是將這個粘性事件添加到了stickyEvents
這個集合中。之后的邏輯雖多,但和粘性事件沒啥關(guān)系。
register內(nèi)部機制
findSubscriberMethods()
這個方法里面的邏輯就不帶大家進行分析了,總之就干了一件事情:
查找當前類通過
@Subscribe
注冊的所有事件訂閱方法,并返回一個List<SubscriberMethod>
集合,其中SubscriberMethod
就是對每個注冊的訂閱方法和當前注冊類的封裝
subscribe
這個方法是關(guān)鍵,深入探究下:
第1、2、3、4步中其實就干了兩件事情:
- 填充
subscriptionsByEventType
集合,key為事件類型,value為通過@Subscribe
訂閱了該事件類型的方法集合 - 填充
typesBySubscriber
集合,key為注冊EventBus的類,value為該類中所有@Subscribe
注解修飾的方法集合
- 填充
第5步就是實現(xiàn)粘性事件分發(fā)的關(guān)鍵地方
- 首先判斷當前
@Subscribe
修飾的訂閱方法是否為粘性,即@Subscribe(sticky = true)
中sticky
等于true - 是的話就從
stickyEvents
集合中判斷是否存在和訂閱方法中注冊的事件類型相同的事件:
這個
stickyEvents
是不是很熟悉,就是我們之前發(fā)送粘性事件時,將粘性事件添加到的方法集合- 如果存在,則就執(zhí)行該粘性事件的分發(fā),即調(diào)用執(zhí)行該訂閱方法,最終會調(diào)用到
invokeSubscriber()
方法:
- 首先判斷當前
從上面可以看到,最終是通過反射來實現(xiàn)的訂閱了粘性事件方法的執(zhí)行。
register小結(jié)
該方法最終會判斷當前是否存在注冊EventBus
前發(fā)送的粘性事件,且當前注冊類中存在訂閱該事件類型的方法,然后立即執(zhí)行。
總結(jié)
以上就是EventBus
粘性事件的內(nèi)部實現(xiàn)機制,總體來說不算復雜,大家看著文章跟著源碼一步步分析應該就很容易理解這部分實現(xiàn)邏輯了。
到此這篇關(guān)于Android EventBus粘性事件實現(xiàn)機制的文章就介紹到這了,更多相關(guān)Android EventBus粘性事件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android activity動畫不生效原因及解決方案總結(jié)
android activity動畫是一個比較簡單的功能。但是使用時總會由于各種小問題導致動畫失效,筆者根據(jù)自己經(jīng)驗,整理了各種可能導致的原因,期望能對你有所幫助2021-11-11淺談Android onTouchEvent 與 onInterceptTouchEvent的區(qū)別詳解
本篇文章小編為大家介紹,Android onTouchEvent 與 onInterceptTouchEvent的區(qū)別詳解。需要的朋友參考下2013-04-04解決android 顯示內(nèi)容被底部導航欄遮擋的問題
今天小編就為大家分享一篇解決android 顯示內(nèi)容被底部導航欄遮擋的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07