1. 程式人生 > >Android EventBus框架入門

Android EventBus框架入門

在Android開發中可能會遇到過這樣一種情況,兩個Activity或者Activity與Service、Activity與後臺執行緒、執行緒與執行緒之間需要頻繁的進行通訊,Android官方的解決方案有兩種,一種是使用Handle,一種是使用廣播,但是這兩種方式都不是很好用,這時候就輪到EventBus出場了!EventBus就以非常簡便的方式解決了這樣的問題~

這裡有一個我寫的小Demo,算是拋磚引玉吧。

EventBus它的思想其實和廣播差不多(什麼!不明白廣播?這可是四大元件之一!可以百度一下),就是傳送訊息和接收訊息,在EventBus中訊息稱為事件,同一時間傳送事件的可以不止一個,同一時間接收事件的也可以不是一個。關於EventBus的思想,還可以參考計算機硬體中的匯流排。

好了,我們來看看如何使用EventBus吧~

1、這第一步肯定是配置Gradle了

compile ‘org.greenrobot:eventbus:3.0.0’

2、事件類

我們使用EventBus傳遞事件的時候要傳遞一個物件,我們可以傳遞自定義類物件,也可以傳遞java型別物件,不過,由於它傳遞的是一個物件,所以如果要傳遞int型別的資料,要傳遞Integer!當然其他型別也是這樣(好多人都會問,我傳遞一個數字怎麼傳不過去啊)

這裡我自定義一個類吧~看程式碼:

package com.mql.www.eventbusdemo.events;

/**
 *
 * Created by MQL on 2017/8/20.
 */

public class MessageEvent {
private String message;

public MessageEvent(String message) {
    this.message = message;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}
}

非常簡單的一個類,只有一個屬性,geter和seter方法以及構造方法。這樣這個自定義類就等著被使用吧~

2、註冊,接收事件

這裡先看看整體程式碼,程式碼下面進行解釋:

public class MainActivity extends AppCompatActivity {
private TextView tv_meaasge;
private Button btn_message;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    EventBus.getDefault().register(this);//註冊

    tv_meaasge = (TextView)findViewById(R.id.main_tv);
    tv_meaasge.setText("MainActivity");

    btn_message = (Button)findViewById(R.id.main_btn);
    btn_message.setText("跳轉到SecondActivity");

    btn_message.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this,SecondActivity.class));
        }
    });
}

@Override
protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);//取消註冊
}

//事件處理
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMoonEvent(MessageEvent messageEvent){
    tv_meaasge.setText(messageEvent.getMessage());
}
}

(1)先看看註冊吧,找出相關程式碼:

EventBus.getDefault().register(this);//註冊

就這樣一行程式碼,這個類或者說這個Activity就已經在EventBus上註冊成功了,那麼註冊有什麼作用呢,這就相當於告訴EventBus:以後只要有事件傳送,你就要通知我,無論在哪個執行緒,無論在哪個類裡面傳送的。

(2)再看看取消註冊,找出相關程式碼:

EventBus.getDefault().unregister(this);//取消註冊

這樣新增一行程式碼,這個類或者說這個Activity就取消了註冊,這就相當於告訴EventBus:以後的事件不需要通知我了。這一行程式碼無論寫在什麼地方都可以生效,一般來講當Activity銷燬時必須要取消註冊,所以我在onDestroy方法中取消了註冊。

看完註冊和取消註冊,他們倆都有一個共同的特點就是都有一個EventBus.getDefault(),這句程式碼會返回一個預設的EventBus物件,當然我們也一個自己構造一個EventBus物件,這要使用EventBusBuilder類,很顯然這是建造者模式(什麼?不知道建造者模式是啥?沒關係目前不需要知道),我們使用這個預設的EventBus物件已經能夠滿足日常需求了。

(3)事件處理,我們找出相關程式碼:

//事件處理
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMoonEvent(MessageEvent messageEvent){
    tv_meaasge.setText(messageEvent.getMessage());
}

首先我們可以看到這裡有一個註解Subscribe(什麼!不明白註解是什麼?看看這篇文章吧),這標識了這個方法為一個EventBus事件處理方法,註解裡面還有一個引數,這個引數的含義是指定事件處理的執行緒,引數可取的值有四個:

POSTING(預設) //這是預設的引數,使用該引數時,事件處理的執行緒與事件發出的執行緒是同一個執行緒,也就是說,該方法接收的事件是從哪個執行緒
中發出的,該方法的處理執行緒就是哪個執行緒。

MAIN //事件處理執行緒是UI執行緒

BACKGROUND //這個引數就有點意思了,如果接收的事件是從UI執行緒發出的,則事件處理會在新執行緒中執行,如果接收的事件是從子執行緒發出的,則
事件處理執行緒和事件發出執行緒是同一個執行緒。

ASYNC //事件處理在新執行緒中執行。

其次,我們這個方法不需要在任何地方手動呼叫,這就是註解的強大作用啦,當有事件傳送時,EventBus會先去找這些被註解了的方法,然後進行事件型別匹配(如果現在不明白,先知道有這麼回事,看完下面的事件傳送就明白了),如果事件型別匹配上,EventBus就會自動呼叫這個方法~

最後,這個方法的名字可以隨意起,阿貓阿狗都可以~

3、事件傳送

我們還是先看下程式碼,下面解釋:

public class SecondActivity extends AppCompatActivity {
private TextView tv_second;
private Button btn_second;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    EventBus.getDefault().register(this);

    tv_second = (TextView)findViewById(R.id.second_tv);

    btn_second = (Button)findViewById(R.id.second_btn);

    btn_second.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Thread() {
                @Override
                public void run() {
                //傳送事件
                    EventBus.getDefault().post(new MessageEvent("我是SecondActivity傳過來的message"));
                }
            }.run();

        }
    });
}
}

我們來單獨看看傳送事件:

EventBus.getDefault().post(new MessageEvent("我是SecondActivity傳過來的message"));

還是先獲取了一個預設的EventBus物件,然後呼叫它的post方法,就這樣,SecondActivity就成功通知EventBus傳送了一條事件,可以看到我們是子執行緒中傳送的,不過我們的接收方法已經用註解標識了在UI執行緒中執行。我們可以看到本次事件傳送的事件型別是一個我們一開始定義好的MessageEvent類自定義型別,回過頭去發現我們接受方法的引數也是一個MessageEvent型別,這樣本次傳送的事件就能被剛剛的接收方法接收並處理,剛剛說的型別匹配也就是這個意思。
當然,如果我們傳送其他型別的事件,比如傳送一個String字串,就像這樣:

EventBus.getDefault().post("我是SecondActivity傳過來的message");

那麼我們剛剛的接收方法就無法接收到事件,因為事件型別不匹配。

對於一個傳送事件來說,接收事件可能不只是一個,只要型別匹配成功,都可以接收。

這樣,一個 傳送事件—接收事件 的過程也就解釋完了。

MQL於2017年8月20日完成本文。