EventBus簡單封裝

前言

之前每一個頁面與每一個頁面業務邏輯傳遞讓你不知所措,一個又一個接口回調,讓你暈頭轉向,一個又一個參數讓你混亂不堪。EventBus一個耦合度低的讓你懼怕的框架。java

什麼是EventBus

EventBus是一個消息總線,以觀察者模式實現,用於簡化程序的組件,能夠輕易切換線程,實現各組件之間的刷新通知,以及參數的傳遞。EventBus3.0跟以前版本的區別框架

是介入了annotation @Subscribe,取代了之前約定命名的方式。異步

EventBus的優勢

它代替了廣播,startActivityforResult,Handle,異步回調等,來實現各個組件間,線程間的通信,優勢是開銷小,代碼更優雅,以及將發送者與接受者解耦。ide

EventBus封裝

咱們今天直接看EventBus封裝過程。post

EventBus的訂閱,接收,發送,咱們都放在基類BaseActivity/BaseFragment中完成(EventBus.getDefault().register(this)訂閱事件,發起通訊的邏輯直接調用EventBus.getDefault().post(Object event)來發布事件)。this

EventBus封裝實戰

在Gradle中添加EventBus依賴:線程

compile 'org.greenrobot:eventbus:3.0.0'

封裝一下EventBus的訂閱、取消訂閱、發佈等方法:code

public class EventBusUtil {

    public static void register(Object subscriber) {
        EventBus.getDefault().register(subscriber);
    }

    public static void unregister(Object subscriber) {
        EventBus.getDefault().unregister(subscriber);
    }

    public static void sendEvent(Event event) {
        EventBus.getDefault().post(event);
    }

    public static void sendStickyEvent(Event event) {
        EventBus.getDefault().postSticky(event);
    }

    // 其餘
}

BaseActivity/BaseFragment中的onCreateonDestroy方法中訂閱和取消訂閱,這裏添加了一個isRegisterEventBus()方法,默認返回false,即不訂閱EventBus,子類Activity/Fragment若是須要訂閱的話複寫這個方法並返回true便可。blog

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (isRegisterEventBus()) {
        EventBusUtil.register(this);
    }
}

/**
 * 是否註冊事件分發
 *
 * @return true綁定EventBus事件分發,默認不綁定,子類須要綁定的話複寫此方法返回true.
 */
protected boolean isRegisterEventBus() {
    return false;
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (isRegisterEventBus()) {
        EventBusUtil.unregister(this);
    }
}

定義事件Event接口

public class Event<T> {
    private int code;
    private T data;

    public Event(int code) {
        this.code = code;
    }

    public Event(int code, T data) {
        this.code = code;
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

經過泛型<T>指定事件通訊過程當中的數據類型,code爲事件碼,使用的時候給不一樣的事件類型指定不一樣的code

BaseActivity\BaseFragment中添加接收到EventBus的方法:

/**
 * 是否註冊事件分發
 *
 * @return true綁定EventBus事件分發,默認不綁定,子類須要綁定的話複寫此方法返回true.
 */
protected boolean isRegisterEventBus() {
    return false;
}

@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventBusCome(Event event) {
    if (event != null) {
        receiveEvent(event);
    }
}

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onStickyEventBusCome(Event event) {
    if (event != null) {
        receiveStickyEvent(event);
    }
}

/**
 * 接收到分發到事件
 *
 * @param event 事件
 */
protected void receiveEvent(Event event) {

}

/**
 * 接受到分發的粘性事件
 *
 * @param event 粘性事件
 */
protected void receiveStickyEvent(Event event) {

}

根據本身項目的需求,在訂閱了EventBusActivity/Fragment中複寫receiveEvent(Event event)receiveStickyEvent(Event event)來處理接收到事件後的邏輯。

這裏也能夠不用在BaseActivty/BaseFragment中添加接受事件的方法(由於添加了事後不能肯定的子類的Event泛型)。那麼就直接在訂閱的Activity/Fragment中給接收事件的方法添加EventBus對應的事件接受註解,並指定參數Event的泛型。

@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventReceived(Event<User> event) {
    if (event != null && event.getCode() == C.EventCode.C) {
        User user = event.getData();
    }
}

在給定Eventcode的時候最好在常量池中定義一個類專門用來定義不一樣類型的EventBuscode,這樣在接收到EventBus的地方能夠根據這些code值來判斷Event的來源。

public final class C {
    // EventBus Code
    public static final class EventCode {
        public static final int A = 0x111111;
        public static final int B = 0x222222;
        public static final int C = 0x333333;
        public static final int D = 0x444444;
        // other more
    }
}

使用示例:
MainActivity中複寫isRegisterEventBus()並返回true註冊EventBus,複寫receiveEvent(Event event)接收發布的事件。

@Override
protected boolean isRegisterEventBus() {
    return true;
}

@Override
protected void receiveEvent(Event event) {
    // 接受到Event後的相關邏輯
    switch (event.getCode()) {
        case C.EventCode.A:
            Log.d("EventBus", "接收到A類型的Event");
            break;
        case C.EventCode.B:
            Log.d("EventBus", "接收到B類型的Event");
            break;
        case C.EventCode.C:
            Log.d("EventBus", "接收到B類型的Event,攜帶User");
            User user = (User) event.getData();
            break;
        case C.EventCode.D:
            Log.d("EventBus", "接收到D類型的Event,攜帶News");
            News news = (News) event.getData();
            break;
    }
}

receiveEvent(Event event)根據對應的事件的code,判斷通訊的數據來源和傳遞的數據類型,以完成對應的邏輯。

InfoActivity中發送事件,InfoActivity只發送不須要接收Event的話就不註冊,也不用複寫isRegisterEventBus()receiveEvent(Event event)方法了。

public void sendEventA(View view) {
    EventBusUtil.sendEvent(new Event(C.EventCode.A));
}

public void sendEventB(View view) {
    EventBusUtil.sendEvent(new Event(C.EventCode.B));
}

public void sendEventC(View view) {
    Event<User> event = new Event<>(C.EventCode.C, new User());
    EventBusUtil.sendEvent(event);
}

public void sendEventD(View view) {
    Event<News> event = new Event<>(C.EventCode.D, new News());
    EventBusUtil.sendEvent(event);
}

經過上面的方式,將EventBus封裝到BaseActivity/BaseFragment中,使得EventBus和項目解耦更加完全,同時在須要使用的子Activity/Fragment中只須要複寫isRegisterEventBus()receiveEvent(Event event)便可,不用每一個地方都去訂閱和取消訂閱。而且給Event給定code和泛型可以很好的區分不一樣的事件來源和數據類型。

相關文章
相關標籤/搜索