EventBus基本用法

來(lái)點(diǎn)閑白
?EventBus是一款針對(duì)Android優(yōu)化的發(fā)布-訂閱事件總線。它簡(jiǎn)化了應(yīng)用程序內(nèi)各組件間、組件與后臺(tái)線程間的通信。其優(yōu)點(diǎn)是開銷小,代碼更優(yōu)雅,以及將發(fā)送者和接收者解耦。如果Activity和Activity進(jìn)行交互還好說(shuō),但如果Fragment和Fragment進(jìn)行交互則著實(shí)令人頭疼。這時(shí)我們會(huì)使用廣播來(lái)處理,但是使用廣播略嫌麻煩并且效率也不高。如果傳遞的數(shù)據(jù)是實(shí)體類,需要序列化,那么傳遞的成本會(huì)有點(diǎn)高。
進(jìn)入正題
?在講到EventBus的基本用法之前,我們需要了解EventBus的三要素以及它的4種ThreadMode。

EventBus的三要素:

  • Event:事件。可以是任意類型的對(duì)象。
  • Subscriber:事件訂閱者。在EventBus3.0之前消息處理的方法只能限定于onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,它們分別代表4中線程模型。而在EventBus3.0之后,事件處理的方法可以隨便取名,但是需要添加一個(gè)注解@Subscribe,并且要指定線程模型(默認(rèn)為POSTING)。4種線程模型下面會(huì)講到。
  • Publisher:事件發(fā)布者??梢栽谌我饩€程位置發(fā)送事件,直接調(diào)用EventBus的post(Object)方法??梢宰约簩?shí)例化EventBus對(duì)象,但一般使用EventBus.getDefault()就可以。根據(jù)post函數(shù)參數(shù)的類型,會(huì)自動(dòng)調(diào)用訂閱相應(yīng)類型的事件的函數(shù)。

EventBus的4種ThreadMode(線程模型)如下:

  • POSTING(默認(rèn)):如果使用事件處理函數(shù)指定了線程模型為POSTING,那么該事件是在那個(gè)線程發(fā)布出來(lái),事件處理函數(shù)就會(huì)在哪個(gè)線程中運(yùn)行,也就是說(shuō)發(fā)布事件和接收事件在同一個(gè)線程中。在線程模型為POSTING的事件處理函數(shù)中盡量避免執(zhí)行耗時(shí)操作,因?yàn)樗鼤?huì)阻塞事件的傳遞,甚至有可能會(huì)引起ANR。
  • MAIN:事件的處理會(huì)在UI線程中執(zhí)行。時(shí)間處理的事件不能太長(zhǎng),太長(zhǎng)會(huì)導(dǎo)致ANR。
  • BACKGROUND:如果時(shí)間是在UI線程中發(fā)不出來(lái)的,那么該事件處理函數(shù)就會(huì)在新的線程中運(yùn)行;如果事件本來(lái)就是在子線程中發(fā)不出來(lái)的,那么該事件處理函數(shù)直接在發(fā)布事件的線程中執(zhí)行。在此事件處理函數(shù)中禁止進(jìn)行UI更新操作。
  • ASYNC:無(wú)論事件在那個(gè)線程中發(fā)布,該事件處理函數(shù)都會(huì)在新建的子線程中執(zhí)行;同樣,此事件處理函數(shù)中禁止UI更新操作。

EventBus基本用法
?EventBus使用起來(lái)分為以下5個(gè)步驟
?(1)自定義一個(gè)事件類型

class MessageEvent{}

?(2)在需要訂閱事件的地方注冊(cè)事件

EventBus.getDefault().register(this);

?(3)發(fā)送事件

EventBus.getDefault().post(messageEvent);

?(4)處理事件

 @Subscribe(threadMode = ThreadMode.MAIN)
 fun EventMain(messageEvent: MessageEvent){
        ...
 }

?前面說(shuō)過(guò),消息處理的方法可以隨便取名,但是需要添加一個(gè)注解@Subscriber,并且要指定線程模型(默認(rèn)為POSTING)。
?(5)取消時(shí)間訂閱

EventBus.getDefault().unregister(this)

EventBus應(yīng)用
?前面說(shuō)到了EventBus的基本用法,但是這個(gè)過(guò)于簡(jiǎn)單,這里舉個(gè)??來(lái)應(yīng)用EventBus。
?(1)添加依賴庫(kù)

implementation 'org.greenrobot:eventbus:3.1.1'

?(2)定義消息事件類

class MessageEvent(var message: String?)

?(3)注冊(cè)和取消訂閱事件

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btn_subscription.setOnClickListener {
            EventBus.getDefault().register(this)
            Toast.makeText(this, "注冊(cè)事件", Toast.LENGTH_LONG).show()
        }
        but_message.setOnClickListener {
            startActivity(Intent(this, SecondActivity::class.java))
        }
    }

   @Subscribe(threadMode = ThreadMode.MAIN)
    fun EventMain(messageEvent: MessageEvent){

    }
    override fun onDestroy() {
        super.onDestroy()
        //取消注冊(cè)事件
        EventBus.getDefault().unregister(this)
    }
}

?在MainActivity中定義兩個(gè)Button;一個(gè)用來(lái)注冊(cè)事件,另一個(gè)用來(lái)調(diào)轉(zhuǎn)到SecondActivity。
?(4)事件訂閱者處理事件
?在MianActivity中自定義方法來(lái)處理事件,在這里ThreadMode設(shè)置為MAIN,事件會(huì)在UI線程中執(zhí)行,用TextView來(lái)展示收到的時(shí)間消息:

@Subscribe(threadMode = ThreadMode.MAIN)
fun EventMain(messageEvent: MessageEvent){
   textView.text = messageEvent.message
}

?(5)事件發(fā)布者發(fā)布事件
?創(chuàng)建了SecondActivity來(lái)發(fā)布消息,代碼所示:

class SecondActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        btn_send_message.setOnClickListener {
            //發(fā)送事件
            EventBus.getDefault().post(MessageEvent("歡迎來(lái)到張三兒的簡(jiǎn)書"))
            finish()
        }
    }
}

?在SecondActivity中,我們定義“事件發(fā)送”按鈕來(lái)發(fā)送事件并將SecondActivity finish掉。運(yùn)行程序。如圖所示。接下點(diǎn)擊MainAcitivity中的“注冊(cè)事件”,然后點(diǎn)擊“跳轉(zhuǎn)到SECONDACTIVITY”按鈕,這時(shí)跳轉(zhuǎn)到SecondActivity,如圖所示,接下來(lái)點(diǎn)擊“發(fā)送事件”按鈕,這個(gè)時(shí)候SecondActivity被finish掉,因此界面展示的是MainActivity如圖所示??梢钥吹組ainActivity的TextView顯示“歡迎關(guān)注張三兒的簡(jiǎn)書”,MainActivity成功的接收到了SecondActivity發(fā)送的事件。


程序初始樣式

調(diào)轉(zhuǎn)到SecondActivity

MainActivity接收到事件

?(6)ProGuard
?最后不要忘記在ProGuard中加入混淆規(guī)則:

-keepattributes *Annotation*
-keepclassmembers class **{
    @org.greenrobot.eventbus.Subscribe<methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode{*;}
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent{
    <init>(java.lang.Throwable);
}

EventBus的黏性事件
?c除了上面講到的普通事件外,EventBus還支持發(fā)送黏性事件,就是在發(fā)送事件之后再訂閱該事件也能收到該事件,這跟黏性廣播類似,為了驗(yàn)證黏性事件,我們修改下以前的代碼。
?(1)訂閱者處理黏性事件
在MainActivity中新寫一個(gè)方法用來(lái)處理黏性事件:

@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
 fun ononMoonStickyEvent(messageEvent: MessageEvent){
        textView.text = messageEvent.message
 }

?(2)發(fā)送黏性事件
?在SecondActivity中定義一個(gè)Button來(lái)發(fā)送黏性事件:

btn_send_message.setOnClickListener {
            //發(fā)送事件
            EventBus.getDefault().postSticky(MessageEvent("粘性事件"))
            finish()
        }

?現(xiàn)在運(yùn)行代碼再來(lái)看看效果,首先,在MianActivity中并沒點(diǎn)擊“注冊(cè)事件”按鈕,而是直接調(diào)轉(zhuǎn)到SecondActivity中點(diǎn)擊發(fā)送“黏性事件”按鈕。這時(shí)界面回到MianActivity,看到TextView依舊顯示著MainActivity的字段,這時(shí)因?yàn)楝F(xiàn)在還沒有訂閱事件。接下來(lái)點(diǎn)擊“注冊(cè)事件”按鈕,TextView內(nèi)容發(fā)生改變,顯示“黏性事件”,說(shuō)明黏性時(shí)間被成功接受到了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 EventBus是一個(gè)Android事件發(fā)布/訂閱框架,通過(guò)解耦發(fā)布者和訂閱者簡(jiǎn)化Android事件傳遞,這...
    々志尚閱讀 520評(píng)論 0 0
  • EventBus用法及源碼解析目錄介紹1.EventBus簡(jiǎn)介1.1 EventBus的三要素1.2 EventB...
    楊充211閱讀 2,054評(píng)論 0 4
  • EventBus是在Android中使用到的發(fā)布-訂閱事件總線框架,基于觀察者模式,將事件的發(fā)送者和接收者解耦,簡(jiǎn)...
    BrotherTree閱讀 236評(píng)論 0 0
  • 前言:EventBus出來(lái)已經(jīng)有一段時(shí)間了,github上面也有很多開源項(xiàng)目中使用了EventBus。所以抽空學(xué)習(xí)...
    Kerry202閱讀 1,374評(píng)論 1 2
  • EventBus 是一款在 Android 開發(fā)中使用的發(fā)布/訂閱事件總線框架,基于觀察者模式,將事件的接收者和發(fā)...
    MonkeyLqj閱讀 10,561評(píng)論 3 31

友情鏈接更多精彩內(nèi)容