RxJava替代EventBus:RxBus

簡(jiǎn)要說(shuō)明

關(guān)于RxJava:https://github.com/ReactiveX/RxJava
關(guān)于EventBus:https://github.com/greenrobot/EventBus
由于最近工程中依賴(lài)于RxAndroid與RxJava亲轨,因此以RxJava模式實(shí)現(xiàn)EventBus相同的API,移除重復(fù)功能的依賴(lài)鸟顺,達(dá)到精簡(jiǎn)工程的目的惦蚊。

第一步:構(gòu)造單例
  1. 在EventBus中
EventBus.getDefault();
  1. 構(gòu)造RxBus相同的API
public class RxBus {    
      private static volatile RxBus instance;    
      private RxBus() {}    
      public static RxBus getDefault() {        
         if (instance == null) {           
             synchronized (RxBus.class) {                
                 if (instance == null) {                    
                     instance = new RxBus();                
                 }            
              }        
         }        
         return instance;    
      }
  1. 在RxBus中
RxBus.getDefault();
第二步:事件注解
  1. 在EventBus中
@Subscribe
public void onMessageEvent(MessageEvent event) {/* Do something */};
  1. 構(gòu)造RxBus相同的API
public class RxBus { 

      //省略第一步...

      @Target(ElementType.METHOD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Subscribe {}
}
  1. 在RxBus中
@RxBus.Subscribe
public void onMessageEvent(MessageEvent event) {/* Do something */};
第三步:訂閱事件
  1. 在EventBus中
@Override
public void onStart() { 
      super.onStart(); 
      EventBus.getDefault().register(this);
}
  1. 構(gòu)造RxBus相同的API
public class RxBus { 

      //省略第一步...

      private final Subject<Object, Object> bus = new SerializedSubject<>(PublishSubject.create());
      private final ArrayMap<String, List<Subscription>> subscriptionArray = new ArrayMap<>();
      
      public void register(final Object observable) {    
          boolean isRegisterSuccess = false;    
          final String subscriptionKey = observable.getClass().getName();
          //反射獲取方法列表  
          Method[] methods = observable.getClass().getMethods();    
          for (Method method : methods) {    
              //如果方法不存在Subscribe注解則不做處理
              if (!method.isAnnotationPresent(Subscribe.class)) continue;        
              final Method subscriptionMethod = method;
              //獲取方法參數(shù)類(lèi)型,即:MessageEvent.class
              Class<?> key = method.getParameterTypes()[0];
              //訂閱MessageEvent.class類(lèi)型實(shí)例讯嫂,ofType作用已filter相近
              Subscription subscription = bus.ofType(key).subscribe(new Action1<Object>() {
                  @Override            
                  public void call(Object value) {
                      try {
                          //反射賦值蹦锋,即傳遞事件值
                          subscriptionMethod.setAccessible(true);
                          subscriptionMethod.invoke(observable, value);
                      } catch (IllegalAccessException | InvocationTargetException e) { 
                          throw new RuntimeException(subscriptionKey + " isn't allowed to register!");
                      }
                  }
              });
              //存儲(chǔ)訂閱實(shí)例列表,用于后續(xù)解除注冊(cè)
              List<Subscription> subscriptions;
              if (subscriptionArray.containsKey(subscriptionKey)) {
                 subscriptions = subscriptionArray.get(subscriptionKey);
              } else {
                 subscriptions = new ArrayList<>();
              }
              subscriptions.add(subscription);
              subscriptionArray.put(subscriptionKey, subscriptions); 
              isRegisterSuccess = true;
          }
          //如果注冊(cè)的類(lèi)中不存在Subscribe注解方法欧芽,則拋出異常提醒
          if (!isRegisterSuccess) 
              throw new RuntimeException(subscriptionKey + " has no any RxBuxSubscribe Event!");
      }

      //省略第二步...
}
  1. 在RxBus中
@Override
public void onStart() { 
      super.onStart(); 
      RxBus.getDefault().register(this);
}
取消訂閱
  1. 在EventBus中
@Override
public void onStop() { 
      super.onStop(); 
      EventBus.getDefault().unregister(this);
}
  1. 構(gòu)造RxBus相同的API
public class RxBus { 

      //省略第一步...
      //省略第三步...

      public void unregister(Object observable) {    
          String subscriptionKey = observable.getClass().getName();
          if (!subscriptionArray.containsKey(subscriptionKey)) return;
          List<Subscription> subscriptions = subscriptionArray.get(subscriptionKey);
          for (Subscription subscription : subscriptions) {
              //如果已訂閱莉掂,則取消訂閱
              if (!subscription.isUnsubscribed()) subscription.unsubscribe();
          }
          subscriptionArray.remove(subscriptionKey);
      }      

      //省略第二步...
}
  1. 在RxBus中
@Override
public void onStop() { 
      super.onStop(); 
      RxBus.getDefault().unregister(this);
}
發(fā)送事件
  1. 在EventBus中
EventBus.getDefault().post(new MessageEvent());
  1. 構(gòu)造RxBus相同的API
public class RxBus { 

      //省略第一步...
      //省略第三步...
      //省略第四步...     
      
      public void post (Object event) { 
          bus.onNext(event);
      }

      //省略第二步...
}
  1. 在RxBus中
RxBus.getDefault().post(new MessageEvent());
關(guān)于ThreadMode

在訂閱時(shí)根據(jù)需要使用RxJava的Schedulers即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末千扔,一起剝皮案震驚了整個(gè)濱河市憎妙,隨后出現(xiàn)的幾起案子库正,更是在濱河造成了極大的恐慌,老刑警劉巖厘唾,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件褥符,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡抚垃,警方通過(guò)查閱死者的電腦和手機(jī)喷楣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鹤树,“玉大人铣焊,你說(shuō)我怎么就攤上這事『辈” “怎么了粗截?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)捣炬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)绽榛,這世上最難降的妖魔是什么湿酸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮灭美,結(jié)果婚禮上推溃,老公的妹妹穿的比我還像新娘。我一直安慰自己届腐,他們只是感情好铁坎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著犁苏,像睡著了一般硬萍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上围详,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天朴乖,我揣著相機(jī)與錄音,去河邊找鬼助赞。 笑死买羞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雹食。 我是一名探鬼主播畜普,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼群叶!你這毒婦竟也來(lái)了吃挑?” 一聲冷哼從身側(cè)響起钝荡,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎儒鹿,沒(méi)想到半個(gè)月后化撕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡约炎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年植阴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圾浅。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡掠手,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狸捕,到底是詐尸還是另有隱情喷鸽,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布灸拍,位于F島的核電站做祝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鸡岗。R本人自食惡果不足惜混槐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轩性。 院中可真熱鬧声登,春花似錦、人聲如沸揣苏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卸察。三九已至脯厨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坑质,已是汗流浹背俄认。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洪乍,地道東北人眯杏。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像壳澳,于是被迫代替她去往敵國(guó)和親岂贩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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

  • 原文鏈接:http://blog.csdn.net/u012810020/article/details/7005...
    tinyjoy閱讀 542評(píng)論 1 5
  • 項(xiàng)目到了一定階段會(huì)出現(xiàn)一種甜蜜的負(fù)擔(dān):業(yè)務(wù)的不斷發(fā)展與人員的流動(dòng)性越來(lái)越大,代碼維護(hù)與測(cè)試回歸流程越來(lái)越繁瑣萎津。這個(gè)...
    fdacc6a1e764閱讀 3,174評(píng)論 0 6
  • 我從去年開(kāi)始使用 RxJava 卸伞,到現(xiàn)在一年多了。今年加入了 Flipboard 后锉屈,看到 Flipboard 的...
    Jason_andy閱讀 5,460評(píng)論 7 62
  • 前言我從去年開(kāi)始使用 RxJava 荤傲,到現(xiàn)在一年多了。今年加入了 Flipboard 后颈渊,看到 Flipboard...
    占導(dǎo)zqq閱讀 9,159評(píng)論 6 151
  • 博文出處:EventBus源碼解析遂黍,歡迎大家關(guān)注我的博客,謝謝俊嗽! 0001B 時(shí)近年末雾家,但是也沒(méi)閑著。最近正好在看...
    俞其榮閱讀 1,298評(píng)論 1 16