EventBus使用詳解

EventBus這個(gè)開源框架出來已經(jīng)很久了眶拉,深的很多開發(fā)者青睞禀酱,由greenrobot組織貢獻(xiàn)(該組織還貢獻(xiàn)了greenDAO)矛洞,是一個(gè)Android事件發(fā)布/訂閱輕量級(jí)框架,通過解耦發(fā)布者和訂閱者簡(jiǎn)化Android事件傳遞为流,EventBus可以代替Android傳統(tǒng)的Intent,Handler,Broadcast或接口函數(shù),在Fragment,Activity,Service線程之間傳遞數(shù)據(jù)航攒,執(zhí)行方法磺陡。

其最大的特點(diǎn)就是:代碼簡(jiǎn)潔,是一種發(fā)布訂閱設(shè)計(jì)模式(觀察者設(shè)計(jì)模式)漠畜。在沒有EventBus之前我們通常用廣播來實(shí)現(xiàn)監(jiān)聽币他,或者自定義接口函數(shù)回調(diào),但有的場(chǎng)景我們也可以直接用Intent攜帶簡(jiǎn)單數(shù)據(jù)憔狞,或者在線程之間通過Handler處理消息傳遞蝴悉。但無論是廣播還是Handler機(jī)制遠(yuǎn)遠(yuǎn)不能滿足我們高效的開發(fā),廣播是四大組件之一瘾敢,許多系統(tǒng)級(jí)的事件都是通過廣播來通知的拍冠,比如說網(wǎng)絡(luò)的變化、電量的變化簇抵,短信發(fā)送和接收的狀態(tài)庆杜,但是廣播是相對(duì)消耗時(shí)間和資源的,Handler雖然簡(jiǎn)單但高復(fù)發(fā)的內(nèi)存泄漏困擾很多初級(jí)開發(fā)者碟摆,那么EventBus會(huì)很好消除這些缺點(diǎn)晃财,那么本節(jié)我們來了解一下他的使用方法,很簡(jiǎn)單的哦焦履,相信以后你也會(huì)愛上的拓劝。

EventBus3.0源碼地址:https://github.com/greenrobot/EventBus


EventBus重要方法和類:

Event 傳遞的事件對(duì)象

Subscriber? 事件的訂閱者

Publisher? 事件的發(fā)布者

ThreadMode 定義函數(shù)在何種線程中執(zhí)行

他們之間的關(guān)系如圖:

那么具體該怎么操作呢? 請(qǐng)往下看

1)在需要訂閱事件的地方注冊(cè)事件嘉裤,可以是Activity或者Fragment中

EventBus.getDefault().register(this@MainActivity)

2)創(chuàng)建Event消息類 —定義事件模型

該類可以不繼承任何基類也不需要實(shí)現(xiàn)任何接口郑临,

class MessageEvent(val progress: Int)

這里我用Kotlin寫的,所以大家看起來會(huì)有些不習(xí)慣屑宠,不過相信大家看起來不會(huì)有問題厢洞,因?yàn)閍ndroid的api是不變得,只是kotlin寫法稍有改變,會(huì)java的同學(xué)學(xué)起Kotlin也會(huì)很容易,由于Google現(xiàn)在墻裂推薦Kotlin躺翻,作為Android開發(fā)者還是不能掉隊(duì)丧叽,所以大家有時(shí)間也多嘗試這門小眾語言,繼續(xù)我們的內(nèi)容公你,

3)產(chǎn)生事件踊淳、發(fā)送事件

EventBus.getDefault().post(MessageEvent(time))

在我們需要傳遞消息的地方將數(shù)據(jù)封裝到消息類Event中發(fā)送出去,這里我們就將數(shù)據(jù)發(fā)送出去了陕靠,我們?cè)趺唇邮苓@條消息呢迂尝? 接著看

4)消費(fèi)事件,處理消息

@Subscribe(threadMode = ThreadMode.MAIN)

fun onEventMessage(event: MessageEvent) {

progress!!.progress = event.progress

}

@Subscribr()注解標(biāo)識(shí)我們的線程模型剪芥,這里我們要更新進(jìn)度條的進(jìn)度垄开,所以制定消費(fèi)事件的線程為主線程,在3.0之前税肪,EventBus還沒有使用注解方式溉躲。消息處理的方法也只能限定于onEvent、onEventMainThread益兄、onEventBackgroundThread和onEventAsync锻梳,分別代表四種線程模型。而在3.0之后净捅,消息處理的方法可以任意命名唱蒸,這是個(gè)很大方便,但是需要添加一個(gè)注解@Subscribe灸叼,并且要指定線程模型(默認(rèn)為PostThread),需要注意的是事件處理函數(shù)的訪問權(quán)限必須為public庆捺,否則會(huì)報(bào)異常古今。

這里我們更新UI中進(jìn)度條進(jìn)度,大家可以在此取出消息內(nèi)容執(zhí)行自己的邏輯滔以。

當(dāng)然捉腥,我們要記得取消訂閱,跟廣播邏輯很相似你画。

override fun onDestroy() {

super.onDestroy()

EventBus.getDefault().unregister(this@MainActivity)

}


回到上面話題線程模型處抵碟,我們來了解這幾個(gè)線程模型具體含義:

在EventBus的事件處理函數(shù)中需要指定線程模型,即指定事件處理函數(shù)運(yùn)行所在的想線程坏匪。在上面我們已經(jīng)接觸到了EventBus的四種線程模型拟逮。那他們有什么區(qū)別呢?在EventBus中的觀察者通常有四種線程模型适滓,分別是PostThread(默認(rèn))敦迄、MainThread、BackgroundThread與Async。

PostThread:如果使用事件處理函數(shù)指定了線程模型為PostThread罚屋,那么該事件在哪個(gè)線程發(fā)布出來的苦囱,事件處理函數(shù)就會(huì)在這個(gè)線程中運(yùn)行,也就是說發(fā)布事件和接收事件在同一個(gè)線程脾猛。在線程模型為PostThread的事件處理函數(shù)中盡量避免執(zhí)行耗時(shí)操作撕彤,因?yàn)樗鼤?huì)阻塞事件的傳遞,甚至有可能會(huì)引起ANR猛拴。

MainThread:如果使用事件處理函數(shù)指定了線程模型為MainThread羹铅,那么不論事件是在哪個(gè)線程中發(fā)布出來的,該事件處理函數(shù)都會(huì)在UI線程中執(zhí)行漆弄。該方法可以用來更新UI睦裳,但是不能處理耗時(shí)操作。

BackgroundThread:如果使用事件處理函數(shù)指定了線程模型為BackgroundThread撼唾,那么如果事件是在UI線程中發(fā)布出來的廉邑,那么該事件處理函數(shù)就會(huì)在新的線程中運(yùn)行,如果事件本來就是子線程中發(fā)布出來的倒谷,那么該事件處理函數(shù)直接在發(fā)布事件的線程中執(zhí)行蛛蒙。在此事件處理函數(shù)中禁止進(jìn)行UI更新操作。

Async:如果使用事件處理函數(shù)指定了線程模型為Async渤愁,那么無論事件在哪個(gè)線程發(fā)布牵祟,該事件處理函數(shù)都會(huì)在新建的子線程中執(zhí)行。同樣抖格,此事件處理函數(shù)中禁止進(jìn)行UI更新操作诺苹。

EventBus黏性事件:

EventBus除了普通事件也支持粘性事件,這個(gè)有點(diǎn)類似廣播分類中的粘性廣播雹拄。本身粘性廣播用的就比較少收奔,為了方便理解成訂閱在發(fā)布事件之后,但同樣可以收到事件滓玖。訂閱/解除訂閱和普通事件一樣坪哄,但是處理訂閱函數(shù)有所不同,需要注解中添加sticky

= true势篡,

findViewById(R.id.button).setOnClickListener {

Thread(Runnable {

time = 0

while (time <= 100) {

EventBus.getDefault().postSticky(MessageEvent(time))

SystemClock.sleep(500)

time += 10

} }).start()

EventBus.getDefault().register(this@MainActivity)

//粘性事件翩肌,在需要的時(shí)候注冊(cè),接受最后一條消息

}

//EventBus.getDefault().register(this@MainActivity)

}

這里我們沒有在onCreate()中注冊(cè)EventBus,我們是收不到廣播的禁悠,其實(shí)這里我們可以另外添加一個(gè)按鈕念祭,在按鈕點(diǎn)擊事件里面注冊(cè)EventBus,我們這里把注冊(cè)這一步放在發(fā)送事件的后面绷蹲,也可以按照剛才說的那種方式把注冊(cè)步驟放到另外一個(gè)button點(diǎn)擊事件里面棒卷。

對(duì)于粘性廣播我們都比較清楚屬于常駐廣播顾孽,對(duì)于EventBus粘性事件也類似,我們?nèi)绻辉傩枰撜承允录覀兛梢砸瞥?/p>

EventBus.getDefault().removeStickyEvent(MessageEvent(time))

或者調(diào)用移除所有粘性事件

EventBus.getDefault().removeAllStickyEvents();

如果對(duì)粘性事件還不是很熟悉的同學(xué)可以再去看看廣播的內(nèi)容比规,也可以將廣播內(nèi)容跟EventBus做個(gè)總結(jié)若厚,設(shè)計(jì)思想及其相似,都是基于觀察者模式蜒什,只是粘性體現(xiàn)在能夠收到訂閱之前發(fā)送的消息测秸。但是它只能收到最新的一次消息,比如說在未訂閱之前已經(jīng)發(fā)送了多條黏性消息了灾常,然后再訂閱只能收到最近的一條消息霎冯。

看到這里,你是不是對(duì)EventBus已經(jīng)有了很好的了解钞瀑,EventBus使用很簡(jiǎn)單沈撞,但是確實(shí)給項(xiàng)目和開發(fā)者帶來很大的方便,有機(jī)會(huì)大家可以嘗試看看EventBus的源碼雕什,從源碼角度更深層次了解EventBus的強(qiáng)大缠俺,本節(jié)就到這兒,我們下次再見4丁R际俊!? 晚安

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末偿警,一起剝皮案震驚了整個(gè)濱河市躏救,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌螟蒸,老刑警劉巖盒使,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異七嫌,居然都是意外死亡忠怖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門抄瑟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人枉疼,你說我怎么就攤上這事皮假。” “怎么了骂维?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵惹资,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我航闺,道長(zhǎng)褪测,這世上最難降的妖魔是什么猴誊? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮侮措,結(jié)果婚禮上懈叹,老公的妹妹穿的比我還像新娘。我一直安慰自己分扎,他們只是感情好澄成,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著畏吓,像睡著了一般墨状。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菲饼,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天肾砂,我揣著相機(jī)與錄音,去河邊找鬼宏悦。 笑死镐确,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肛根。 我是一名探鬼主播辫塌,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼派哲!你這毒婦竟也來了臼氨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤芭届,失蹤者是張志新(化名)和其女友劉穎储矩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褂乍,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡持隧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逃片。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屡拨。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖褥实,靈堂內(nèi)的尸體忽然破棺而出呀狼,到底是詐尸還是另有隱情,我是刑警寧澤损离,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布哥艇,位于F島的核電站,受9級(jí)特大地震影響僻澎,放射性物質(zhì)發(fā)生泄漏貌踏。R本人自食惡果不足惜十饥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祖乳。 院中可真熱鬧逗堵,春花似錦、人聲如沸凡资。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隙赁。三九已至垦藏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伞访,已是汗流浹背掂骏。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厚掷,地道東北人弟灼。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冒黑,于是被迫代替她去往敵國和親田绑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 前言:EventBus出來已經(jīng)有一段時(shí)間了抡爹,github上面也有很多開源項(xiàng)目中使用了EventBus掩驱。所以抽空學(xué)習(xí)...
    Kerry202閱讀 1,282評(píng)論 1 2
  • 前言:EventBus出來已經(jīng)有一段時(shí)間了,github上面也有很多開源項(xiàng)目中使用了EventBus冬竟。所以抽空學(xué)習(xí)...
    Lauren_Liuling閱讀 48,426評(píng)論 23 155
  • 前言 最近在公司做一個(gè)類似于手機(jī)工廠模式的一個(gè)項(xiàng)目欧穴,用來檢測(cè)其他各個(gè)App是否正常工作,所以要求是盡可能的輕量級(jí)泵殴,...
    Luckily_Liu閱讀 1,173評(píng)論 2 8
  • 本文的EventBus,是指greenrobot的 EventBus, 主要以EventBus3.0 講解; 什么...
    Simon_z閱讀 5,142評(píng)論 2 2
  • 目錄 1.概述 2.實(shí)戰(zhàn) 1.基本框架搭建 2.新建一個(gè)類FirstEvent 3.在要接收消息的頁面注冊(cè)Even...
    慕涵盛華閱讀 10,488評(píng)論 2 16