Rxjava和EventBus的使用比较

EventBus订阅发布模式

  • 概念:EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。
  • EventBus比较适合仅仅当做组件间的通讯工具使用,主要用来传递消息。
  • 使用EventBus可以避免搞出一大推的interface

使用方法

添加依赖
compile 'org.greenrobot:eventbus:3.0.0'
注册
  • 在onStart()方法中注册
  //注册eventBus
    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    //取消注册
    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }
订阅者
  • @Subscribe注解来描述一个public无返回值的非静态方法,注解后面可以跟threadMode,来给定订阅者处理事件所在的线程。
@Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(IdEvent event) {

        if (event != null) {
            System.out.println("onEventMainThread:"+event.getId()+" "+Thread.currentThread().getName());
            textView.setText(""+event.getId());
        }else {
            System.out.println("event:"+event);
        }
    }
  • EventBus包含4个ThreadMode
  • ThreadMode.POSTING
  • ThreadMode.MAIN
  • ThreadMode.BACKGROUND
  • ThreadMode.ASYNC
/**
     * 在后台线程中执行,如果当前线程是子线程,则会在当前线程执行,如果当前线程是主线程,则会创建一个新的子线程来执行
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void  onEventBackgroundThread(MessageEvent event){
        System.out.println("onEventBackgroundThread::"+" "+Thread.currentThread().getName());
    }

    /**
     * 创建一个异步线程来执行
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEventAsync(MessageEvent event){
        System.out.println("onEventAsync::"+" "+Thread.currentThread().getName());
    }

    /**
     * 在主线程中运行
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMain(MessageEvent event){
        System.out.println("onEventMain::"+" "+Thread.currentThread().getName());
    }

    /**
     *默认的线程模式,在当前线程下运行。如果当前线程是子线程则在子线程中,当前线程是主线程,则在主线程中执行。
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEventPosting(MessageEvent event){
        System.out.println("onEventPosting::"+" "+Thread.currentThread().getName());
    }
发布者
  • 不管发布者是在主线程还是子线程,发布的消息在所有定义好的实体类型订阅者中都可以接收到消息。也就是,可以实现一个订阅者订阅多个事件,和一个事件对应多个订阅者。
EventBus.getDefault().post(new MessageEvent("你好!"));
以下是测试的结果图:
  • 在主线程中测试的结果

  • 发生的是另外的实体类型

  • 在子线程中发布消息


RxJava

  • 概念:”a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库),简单的用中文概括也就是两个字:异步。
  • RxJava 的优势即是简洁,但它的简洁的与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁。

使用方法

添加依赖
  compile 'io.reactivex.rxjava2:rxjava:2.0.1'
    //RxAndroid的依赖包
  compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
被观察者与观察者
  • Observeable(被观察者)/Observer(观察者)
  • Flowable(被观察者)/Subscriber(观察者)
  • 2.x中提供了以上两种观察者与被观察者的关系。
  • Observeable用于订阅Observer,是不支持背压的,而Flowable用于订阅Subscriber,是支持背压(Backpressure)的。
  • 背压的概念是:指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略。
//被观察者在主线程中,每1ms发送一个事件
Observable.interval(1, TimeUnit.MILLISECONDS)
                //.subscribeOn(Schedulers.newThread())
                //将观察者的工作放在新线程环境中
                .observeOn(Schedulers.newThread())
                //观察者处理每1000ms才处理一个事件
                .subscribe(new Action1() {
                      @Override
                      public void call(Long aLong) {
                          try {
                              Thread.sleep(1000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          Log.w("TAG","---->"+aLong);
                      }
                  });
  • 在上面的代码中,被观察者发送事件的速度是观察者处理速度的1000倍

  • 这段代码运行之后:

  ...
  Caused by: rx.exceptions.MissingBackpressureException
  ...
  ...
  • 所以在2.x之后使用Flowable支持被压的被观察者,一般而言,上游的被观察者会响应下游观察者的数据请求,下游调用request(n)来告诉上游发送多少个数据。这样避免了大量数据堆积在调用链上,使内存一直处于较低水平。
   Flowable t = Flowable.create(new FlowableOnSubscribe() {
            @Override
            public void subscribe(FlowableEmitter e) throws Exception {
                e.onNext("hello Rx2.0.");
                e.onComplete();
            }
        }, BackpressureStrategy.BUFFER);
  • 下游被观察者subscriber 告知上游请求的数据
  • 我们需要调用request去请求资源,参数就是要请求的数量,一般如果不限制请求数量,可以写成Long.MAX_VALUE。如果你不调用request,Subscriber的onNext和onComplete方法将不会被调用。
Subscriber subscriber = new Subscriber() {
            @Override
            public void onSubscribe(Subscription s) {
                System.out.println("onSubscribe()");
                s.request(Long.MAX_VALUE);
            }

            @Override
            public void onNext(Object o) {
                System.out.println(""+o.toString());
            }

            @Override
            public void onError(Throwable t) {

            }

            @Override
            public void onComplete() {

            }
        };

除了上面这两种观察者,还有一类观察者
* Single/SingleObserver ——— 返回泛型数据的结果给观察者
* Completable/CompletableObserver ——– 返回完成的结果
* Maybe/MaybeObserver ——– 前两者的复合体
* Single为例:

Single.create(new SingleOnSubscribe() {
            @Override
            public void subscribe(SingleEmitter e) throws Exception {
                e.onSuccess(10);
            }
        }).subscribe(new SingleObserver() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("onSubscribe()");
            }

            @Override
            public void onSuccess(Integer value) {
                System.out.println("onSuccess:"+value);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError()");
            }
        });
  • 显示结果:
12-06 10:20:35.278 21057-21057/com.flw.rx20_demo I/System.out: onSubscribe()
12-06 10:20:35.278 21057-21057/com.flw.rx20_demo I/System.out: onSuccess:10
  • Completable为例:
 Completable.create(new CompletableOnSubscribe() {
            @Override
            public void subscribe(CompletableEmitter e) throws Exception {
                System.out.println("subscribe");
                e.onComplete();
            }
        }).subscribe(new CompletableObserver() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("onSubscribe");
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError");
            }
        });

显示结果:

12-06 10:02:31.964 4341-4341/? I/System.out: onSubscribe
12-06 10:02:31.964 4341-4341/? I/System.out: subscribe
12-06 10:02:31.964 4341-4341/? I/System.out: onComplete
  • Maybe为例:
Maybe.create(new MaybeOnSubscribe() {
            @Override
            public void subscribe(MaybeEmitter e) throws Exception {
                System.out.println("subscribe()");
                e.onSuccess("hello Maybe.");
                e.onComplete();
            }
        }).subscribe(new MaybeObserver() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("onSubscribe()");
            }

            @Override
            public void onSuccess(String value) {
                System.out.println("onSuccess():"+value);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError():"+e);
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete()");
            }
        });
  • 打印结果如下:
12-06 10:37:35.605 3344-3344/com.flw.rx20_demo I/System.out: onSubscribe()
12-06 10:37:35.605 3344-3344/com.flw.rx20_demo I/System.out: subscribe()
12-06 10:37:35.605 3344-3344/com.flw.rx20_demo I/System.out: onSuccess():hello Maybe.

Rxjava内置了几个 Scheduler:

  • Schedulers.immediate() 默认的,直接在当前线程运行。
  • Schedulers.newThread() 启用新线程,在新线程工作。
  • Schedulers.io() I/O操作(读写文件,读写数据库,网络信息交互等)、和newThread()最大的区别是:io()内部实现是一个无数量上限的线程池,可以重用空闲的线程。
  • Schedulers.computation():计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • AndroidSchedulers.mainThread() Android专用的,指定的操作在Android的主线程运行。
subscribeOn()和observerOn()
  • subscribeOn() 指定subscribe() 所发生的线程,即 Observable.OnSubcribe 被激活时所处的线程,或者叫事件产生的线程。

  • observerOn() 指定Subscriber 运行所在的线程,或者叫做事件消费的线程。


Rxjava常用的操作符

  • create
    create操作符是所有创建型操作符的“根”,也就是说其他创建型操作符最后都是通过create操作符来创建Observable的.
  • from
    from操作符是把其他类型的对象和数据类型转化成Observable,接收一个集合作为输入。
  • just
    just操作符也是把其他类型的对象和数据类型转化成Observable,它和from操作符很像,只是方法的参数有所差别。接收一个可变参数作为输入。
  • defer
    defer操作符是直到有订阅者订阅时,才通过Observable的工厂方法创建Observable并执行,defer操作符能够保证Observable的状态是最新的
  • timer
    隔一段时间产生一个数字,然后就结束,也就是延迟时间接受到数据。timer操作符默认情况下是运行在一个新线程上的,当然你可以通过传入参数来修改其运行的线程。
  • interval
    interval操作符是每隔一段时间就产生一个数字,这些数字从0开始,一次递增1直至无穷大。
  • range
    range操作符是创建一组在从n开始,个数为m的连续数字,比如range(3,10),就是创建3、4、5…12的一组数字
  • map
    map函数只有一个参数,参数一般是Func1,Func1的
必要解释下一些操作符的使用:
  • timer:

  // o 指的是Observable对象,在全局定义了
  //相当于延迟两秒接收到被观察者发生的数据
       o.timer(2,TimeUnit.SECONDS,Schedulers.newThread())
                .subscribe(observer);
  • interval:

  //从0开始递增,每隔2s递增1,一直递增至无穷大
        o = Observable.interval(2,TimeUnit.SECONDS);
        o.subscribe(observer);
综合来看rxjava,也就是以下四点:
  • 作用 - 异步
  • 模式 - 观察者模式
  • 结构 - 响应式编程
  • 优势 - 逻辑简洁

Rxjava和eventbus使用对比:

  • 如果一个订阅者需要注册多个事件的时候,Rxjava需要一个个单独的注册,而EventBus则可以实现一个订阅者订阅多个事件,和一个事件对应多个订阅者。所以在Rxjava的基础上有了Rxbus来作为事件总线的库。这里不做Rxbus的解释。

你可能感兴趣的:(android,android)