EventBus框架初解

EventBus其實(shí)解決了這樣幾個問題:保存訂閱者、發(fā)布事件、切換線程价捧、粘性事件

保存訂閱者

在register(this)時,處理運(yùn)行時注解涡戳,根據(jù)this找到類和類中的方法结蟋,根據(jù)方法的Subscribe注解找到訂閱事件的那些方法。
從Subscribe注解中找到指定的線程渔彰、優(yōu)先級椎眯、粘滯等;
從方法參數(shù)中找到訂閱的事件類eventType胳岂;
生成訂閱者Subscription對象,內(nèi)有訂閱的類和方法的引用
然后用eventType做key舔稀,把訂閱者存入concurrentHashMap中乳丰,因為一個eventType可能有多個訂閱者,而且是典型讀多寫少的場景内贮,所以用CopyOnWriteArrayList來保存這些訂閱者产园。

發(fā)布事件

在post時,根據(jù)eventType夜郁,從concurrentHashMap中尋找訂閱者什燕。
會根據(jù)父類查找,eventType是根據(jù)對象的類和父類一起判斷的竞端,所以會根據(jù)一個類的列表去查詢訂閱者屎即。
會排隊處理,為了確保一個接一個地發(fā)送事件事富,post其實(shí)是先進(jìn)入隊列Queue技俐,然后每次從隊列中彈一個event來處理的,這個隊列是個普通的List统台,實(shí)際上作為FIFO處理雕擂。

切換線程

同一個事件的不同訂閱者,可能需要不同的線程去執(zhí)行贱勃。
在找到訂閱者處理時井赌,根據(jù)訂閱者要求的線程模式谤逼,做個switch處理:

        switch (subscription.subscriberMethod.threadMode) {
            case POSTING:
                invokeSubscriber(subscription, event);
                break;
            case MAIN:
                if (isMainThread) {
                    invokeSubscriber(subscription, event);
                } else {
                    mainThreadPoster.enqueue(subscription, event);
                }
                break;
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
            case ASYNC:
                asyncPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }

可以看到,有默認(rèn)仇穗、mainThreadPoster流部、backgroundPoster、asyncHandler四類仪缸。
默認(rèn)會在當(dāng)前線程直接invokeSubscriber贵涵,傳遞事件給訂閱者。
mainThreadPoster其實(shí)就是一個持有主線程Looper的handler恰画,利用handler消息機(jī)制宾茂,實(shí)現(xiàn)在主線程的handleMessage函數(shù)里調(diào)用eventbus的invokeSubscriber。
backgroundPoster和asyncPoster都是Runnable拴还,都是獲取eventbus中的ExecutorService來處理跨晴,不過
asyncPoster對于隊列沒做什么特殊處理,每個事件都會一個線程片林。
而backgroundPoster做了入隊列的鎖同步端盆,在出隊列處理時,還可以等待1000毫秒:

PendingPost pendingPost = queue.poll(1000);

其實(shí)就是說费封,backgroundPoster會盡量復(fù)用線程焕妙。

粘滯消息

一般事件是訂閱在先,接收在后弓摘,但是有些情況下焚鹊,事件已經(jīng)發(fā)送,再去訂閱時還希望能拿到這個事件韧献,這時候就需要粘性事件末患。
粘性事件的注冊也是在注解中:

@Subscribe(sticky = true)

而粘性事件的發(fā)送也有專門的函數(shù):

EventBus.getDefault().postSticky(new MessageEvent("xxx"));  
EventBus.getDefault().getStickyEvent(MessageEvent.class);
EventBus.getDefault().removeStickyEvent(stickyEvent); 

粘性事件的實(shí)現(xiàn)原理,也是EventBus維持了一個concurrentHashMap類型的stickyEvents锤窑,這個Map的key是event.Class璧针,value則是event本身。
粘性事件的發(fā)送有兩個入口:
一是postSticky渊啰,每次都會先更新stickyEvents中的數(shù)據(jù)探橱,然后post這個event。
二是register虽抄,相當(dāng)于補(bǔ)發(fā)事件走搁,實(shí)現(xiàn)粘滯效果,具體是在每次register時迈窟,會查詢stickyEvent集合中私植,有沒有粘性事件,如果有车酣,就補(bǔ)發(fā)曲稼。

參考

EventBus源碼分析(三)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末索绪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贫悄,更是在濱河造成了極大的恐慌瑞驱,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窄坦,死亡現(xiàn)場離奇詭異唤反,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鸭津,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門彤侍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逆趋,你說我怎么就攤上這事盏阶。” “怎么了闻书?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵名斟,是天一觀的道長。 經(jīng)常有香客問我魄眉,道長砰盐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任坑律,我火速辦了婚禮楞卡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘脾歇。我一直安慰自己,他們只是感情好淘捡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布藕各。 她就那樣靜靜地躺著,像睡著了一般焦除。 火紅的嫁衣襯著肌膚如雪激况。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天膘魄,我揣著相機(jī)與錄音乌逐,去河邊找鬼。 笑死创葡,一個胖子當(dāng)著我的面吹牛浙踢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灿渴,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼洛波,長吁一口氣:“原來是場噩夢啊……” “哼胰舆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹬挤,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤缚窿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后焰扳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倦零,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年吨悍,在試婚紗的時候發(fā)現(xiàn)自己被綠了扫茅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡诞帐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出爆雹,到底是詐尸還是另有隱情,我是刑警寧澤钙态,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站册倒,受9級特大地震影響蚓挤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驻子,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一灿意、第九天 我趴在偏房一處隱蔽的房頂上張望崇呵。 院中可真熱鬧缤剧,春花似錦域慷、人聲如沸荒辕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抵窒。三九已至,卻和暖如春叠骑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宙枷。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工付材, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人圃阳。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像富寿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锣夹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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

  • EventBus用法及源碼解析目錄介紹1.EventBus簡介1.1 EventBus的三要素1.2 EventB...
    楊充211閱讀 1,888評論 0 4
  • EventBus源碼分析(一) EventBus官方介紹為一個為Android系統(tǒng)優(yōu)化的事件訂閱總線,它不僅可以很...
    蕉下孤客閱讀 3,980評論 4 42
  • 項目到了一定階段會出現(xiàn)一種甜蜜的負(fù)擔(dān):業(yè)務(wù)的不斷發(fā)展與人員的流動性越來越大变勇,代碼維護(hù)與測試回歸流程越來越繁瑣贴唇。這個...
    fdacc6a1e764閱讀 3,174評論 0 6
  • 最近在項目中使用了EventBus(3.0)搀绣,覺得非常好用戳气,于是就看了一些關(guān)于EventBus源碼分析的文章链患,現(xiàn)在...
    shenhuniurou閱讀 1,494評論 0 4
  • 午后的陽光 照水傾城 我依欄醉酒 蘸取一世傷愁. 遙想那畔 浮花照水的小城 伊正春風(fēng) 花正濃 相識桃花池閣 相守明...
    你予的暖閱讀 317評論 0 1