EventBus的優化——KeventBus

一、前言

eventbus3.0的優缺點分析:

eventbus基於觀察者模式,用很少的代碼,幫我們實現很多功能,使我們的代碼變得很優雅。但是大面積的使用eventbus之後,會發現一些很嚴重的問題

  • 需要創建很多的類來區分訂閱方法,訂閱的方法越多,類越多,代碼越多,apk的體積越大
  • 以類來貫穿這個事件傳遞的方式,廣播方式發送問題後,排查事件源或訂閱方法的難度比較大
  • 需要寫很多的訂閱方法,訂閱方法滿天飛,很容易發生dex方法數超出
  • 發送的廣播無法收到返回值
  • 不知道private的訂閱方法,不知道eventbus爲什麼要這麼設計
  • 明明不用發送數據,只是通知,也需要傳遞一個類
  • 無法取消單獨的某一個訂閱的方法

圍繞這個上面幾個問題,我在eventbus的基礎上進行了改善。


二、改善說明: 基於android eventbus 3.0 版本優化:

  • 優化前期以類爲區分監聽接收對象,需要創建很多類,優化後採用字符串方式作爲事件event-key區分代替以類的方式,避免創建太多類,減少代碼量,比較優雅,本思想也參考ios通知的實現。

  • 支持返回值,支持private和static的方法

  • 優化前,訂閱者需要訂閱很多監聽方法來區分分類,優化後可以減少監聽方法,在一個方法或多個方法裏面進行分類判斷即可,思想來自handler

  • 優化前維護難,表現在不清楚事件發生源,優化後,可以統一管理事件vent key,方便管理查找bug

  • 支持只發送事件的功能

  • 支持冷凍事件方法,和解除冷凍事件的方法

其他方面如Subscribe訂閱方法,線程模式的,粘性事件等的處理均和eventbus3.0的處理一致。

項目使用:
androidstudio gradle 引入:implementation ‘com.github.chenjk-520:keventbus:1.1’
項目開源地址:github地址
,如果覺得好用就給個Star或給個打賞吧。如果需要改進的地方,清在下面評論或發送私信到我的郵件[email protected]


三、使用說明

和eventbus3.0版本的使用方式差不多,是eventbus3.0改進,下面看看怎麼使用

  • 瞭解使用之前先了解一下其中一個關鍵的類EventMessage
     private T msg;
     private String event;
     private int arg;
     private CallBack callBack;

msg是我們需要發送的數據,可以是任何數據
event是我們一個事件對應的event,通過這個event我們可以找到訂閱的方法。
arg,是event的在一次分類
callBack 是處理髮送廣播後的回調。

1.註冊事件與取消註冊事件

註冊事件:

  KeventBus.getDefault().register(this);

取消註冊事件:
 
  KeventBus.getDefault().unregister(this);

2. 只使用event-key,不發送數據

發送事件:

 KeventBus.getDefault().post(TestKey.SAY_HELLO);

接收事件:

@Subscribe(event = TestKey.SAY_HELLO,threadMode = ThreadMode.MAIN)
public void hello(EventMessage<String> msg){
    Log.i("TAG",msg.getEvent());
}
其中post事件TestKey.SAY_HELLO,與@Subscribe的event = TestKey.SAY_HELLO一一對應纔可以接收到

3. 使用event-key,併發送數據

發送事件:

 KeventBus.getDefault().post(new EventMessage<>("say hello!",TestKey.SAY_HELLO));

這裏的構造函數參數分別是msg,event

接收數據:

  @Subscribe(event = TestKey.SAY_HELLO,threadMode = ThreadMode.MAIN)
  public void hello(EventMessage<String> msg){
      Log.i("TAG",msg.getMsg());
  }

4. 使用event-key,併發送數據, 在同一訂閱方法裏面再區分,有點類似handler的message,event相當於是what屬性,arg也跟message的arg一樣

發送事件1:

     KeventBus.getDefault().post(new EventMessage("data==1",TestKey.SAY_HELLO,1));

發送事件2:

     KeventBus.getDefault().post(new EventMessage("data==2",TestKey.SAY_HELLO,2));

這裏的構造函數參數分別是msg,event,arg

接收事件:

      @Subscribe(event = TestKey.SAY_HELLO,threadMode = ThreadMode.MAIN)
      public void hello34(EventMessage<String> msg){
        if (msg.getArg() == 1){
            Toast.makeText(this,msg.getMsg(),Toast.LENGTH_SHORT).show();
        }else if(msg.getArg() == 2 ){
            Toast.makeText(this,msg.getMsg(),Toast.LENGTH_SHORT).show();
        }
     }

5. 支持發送訂閱消息後回調

發送訂閱消息:

        KeventBus.getDefault().post(new EventMessage<String>("測試data",TestKey.SAY_HELLO, new EventMessage.CallBack<String>() {
                        @Override
                        public void onCall(String result, int arg) {
                            //在這裏處理回調數據
                            Log.i("TAG",result);
                        }
                    }));

接收事件:

        @Subscribe(event = TestKey.SAY_HELLO4,threadMode = ThreadMode.ASYNC,enback = true)
        private String hello5(EventMessage msg){
            Log.i("TAG",msg.getMsg());
            return "測試返回值";
        }                       

注意:
1.接收事件需要加上enback = true
2.這裏的回調之後的是接收事件的線程,如果在主線程裏面發出的,在子線程接收並返回的事件,回調的方法是接收方法的線程,如果需要toast的話,需要自己切換到主線程再處理

5. 支持冷凍事件和激活事件

說明: 冷凍事件後,發送相對應的事件,訂閱的方法將不能接收到這個時間,但這個訂閱的方法並沒有真的移除掉,可以通過重新激活這個方法,下次發送便可以再接收到

冷凍方法:

      KeventBus.getDefault().freezeSubscribeEvent(TestKey.SAY_HELLO);

激活方法:

     KeventBus.getDefault().activeEvent(TestKey.SAY_HELLO);  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章