EventBus和RxBus的使用

EventBus介绍:

Rx:函数响应式编程,EventBus:事件总线 。
EventBus 功能类似handler,通过一个类来发送post()信息,具体使用方法如下:

  • 发送:

     EventBus.getDefault().post(new EventBussBean("demo执行了"));
    
  • 两种接收方式:

    EventBus注册 :EventBus.getDefault().register(this);  
    EventBus反注册:EventBus.getDefault().unregister(this);  
    
  1. 用自带的方法接收,有4个方法:

    • onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
    • onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
    • onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
    • onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.

    注意: Activity中当有多个onEvent(或其他3个)时,参数的不同则是区分的关键:

    public void onEventMainThread(FirstEvent event) {  
    
    Log.d("harvic", "onEventMainThread收到了消息:" + event.getMsg());  
     }  
    
    public void onEventMainThread(SecondEvent event) {  //消息会根据接收类的不同,自动区分调用
    
        Log.d("harvic", "onEventMainThread收到了消息:" + event.getMsg());  
    } 
    
  2. 自定义接收方法:

    * 先在onCreate中注册: EventBus.getDefault().register(this);
    * 然后自定义接收方法:
     @Subscribe(sticky = true,threadMode = ThreadMode.POSTING) //粘性sticky作用:能接收到注册前的消息,发送时也需用postSticky();
        public void getMessage (EventBussBean evn) {
            evn.execute1();
            }  
    * 最后反注册:EventBus.getDefault().unregister(this); 
    

.

RxBus介绍:

EventBus采用事件总线,RxBus采用函数响应式编程方式实现,二者用谁做事件传递均可;

RxJava提供给开发者5种Subject:

PublishSubject:只会给把订阅的时间点之后的数据发送给观察者。
BehaviorSubject:在订阅者订阅时,会发送其最近发送的数据(如果此时还没有收到任何数据,它会发送一个默认值)。
ReplaySubject:在订阅者订阅时,会发送所有的数据给订阅者,无论它们是何时订阅的。
AsyncSubject:只在原Observable事件序列完成后,发送最后一个数据,后续若还有订阅者继续订阅该Subject, 则可以直接接收到最后一个值
SerializedSubject:待定;

RxBus是自己定义出来的,可用于替代handler和EventBus,主要用来处理应用程序间各个组件的通信,或者组件与组建之间的数据传递,不用再像BroadcastReceiver一样,把数据封装到intent里面再传递出去了。RxBus学的是一种思路,RxBus其实就是对Subject(Observable和Observer的子类)的功能的封装( class Subject<T, R> extends Observable<R> implements Observer<T> {})。

  • RxBus自定义:
 public class RxBus {
       private static volatile RxBus mDefaultInstance;
       private final Subject<Object, Object> mBus;
       private final Map<Class<?>, Object> mStickyEventMap;

       public RxBus() {
          mBus = new SerializedSubject<>(PublishSubject.create());
          mStickyEventMap = new ConcurrentHashMap<>();
       }

      public static RxBus getDefault() {
         if (mDefaultInstance == null) {
           synchronized (RxBus.class) {
               if (mDefaultInstance == null) {
                   mDefaultInstance = new RxBus();
               }
           }
       }
       return mDefaultInstance;
     }

   /**
    * 发送事件
    */
    public void post(Object event) {
       mBus.onNext(event);
    }

   /**
    * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
    */
     public <T> Observable<T> toObservable(Class<T> eventType) {
       return mBus.ofType(eventType);
     }

   /**
    * 判断是否有订阅者
    */
    public boolean hasObservers() {
       return mBus.hasObservers();
    }

    public void reset() {
       mDefaultInstance = null;
   }

    /**
    * Stciky 相关
    */

   /**
    * 发送一个新Sticky事件
    */
    public void postSticky(Object event) {
       synchronized (mStickyEventMap) {
           mStickyEventMap.put(event.getClass(), event);
       }
       post(event);
   }

    /**
    * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
    */
     public <T> Observable<T> toObservableSticky(final Class<T> eventType) {
       synchronized (mStickyEventMap) {
           Observable<T> observable = mBus.ofType(eventType);
           final Object event = mStickyEventMap.get(eventType);

           if (event != null) {
                return observable.mergeWith(Observable.create(new Observable.OnSubscribe<T>() {
                   @Override
                   public void call(Subscriber<? super T> subscriber) {
                       subscriber.onNext(eventType.cast(event));
                   }
               }));
           } else {
               return observable;
           }
       }
   }

   /**
    * 根据eventType获取Sticky事件
    */
   public <T> T getStickyEvent(Class<T> eventType) {
       synchronized (mStickyEventMap) {
           return eventType.cast(mStickyEventMap.get(eventType));
       }
   }

   /**
    * 移除指定eventType的Sticky事件
    */
   public <T> T removeStickyEvent(Class<T> eventType) {
       synchronized (mStickyEventMap) {
           return eventType.cast(mStickyEventMap.remove(eventType));
       }
   }

   /**
    * 移除所有的Sticky事件
    */
    public void removeAllStickyEvents() {
       synchronized (mStickyEventMap) {
           mStickyEventMap.clear();
       }
   }
}

  • RxBus使用举例
   /*
   * 发送端:
   * 可以替换成String类型post(new BaseBean ());接收处toObservableSticky(String.class)
   */
   RxBus.getDefault().post(new BaseBean ()); 

  /*
   * 接收端:
   */
   RxBus.getDefault().toObservableSticky(BaseBean.class)
       //在io线程进行订阅,可以执行一些耗时操作
       .subscribeOn(Schedulers.io())
       //在主线程进行观察,可做UI更新操作
       .unsubscribeOn(Schedulers.io())
       .observeOn(AndroidSchedulers.mainThread())
       //观察的对象
       .subscribe(user->{
         //获取到了一个对象,user  
         Toast.makeText(this,user.getUsername(),Toast.LENGTH_SHORT).show();
       });

注意:Subscription、Observer都是接口,Subscriber是抽象类,Observable是普通类;

.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容