RxJava的简介和使用

RxJava的简介和使用

RxJava是什么

github地址:https://github.com/ReactiveX/RxJava > a library for composing asynchronous and event-based programs using observable sequences for the Java VM. >
一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库RxJava的特点是:简洁 并且随着程序逻辑变得越来越复杂,它依然能够保持简洁

API 介绍和原理简析

RxJava的观察者模式

  • RxJava 的异步实现,是通过一种扩展的观察者模式来实现的。 观察者模式有时被称作发布/订阅模式,其定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
  • RxJava 有四个基本概念:Observable (可观察者,即被观察者)、 Observer (观察者)、 subscribe (订阅)、事件。Observable 和 Observer 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer。- 观察者模式大致如下图:


    观察者模式关系图

    RxJava不仅把每个事件单独处理,还把事件放在一个队列里面处理,RxJava事件的回调方法除了onNext()方法(相当于onEvent,队列中的一个事件完成时调用onNext方法),还定义了两个特殊的回调方法onCompleted()和onError(), 2.0版本还增加了onSubscribe回调方法;

  • onCompleted():事件队列处理完成后回调该方法.
  • 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。
  • 在一个正确运行的事件序列中, onCompleted() 和 onError() 有且只有一个,并且是事件序列中的最后一个。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。
  • onSubscribe 在订阅后发送数据之前,会首先调用这个方法,并提供了可用于取消订阅的方法RxJava 的观察者模式大致如下图:


    RxJava观察者模式关系图

创建 ObserverObserver 即观察者,它决定事件触发的时候将有怎样的行为.

RxJava 中的 Observer 接口的实现方式:

Observer mObserver = new Observer() {            //2.0版本新加入的            //在订阅后发送数据之前,会首先调用这个方法          
 //Disposable可用于取消订阅            
@Override           
public void onSubscribe(@NonNull Disposable d) {            
}            
@Override            
public void onNext(@NonNull Object o) {            
}            
@Override            
public void onError(@NonNull Throwable e) {            
}            
@Override            
public void onComplete() {            
}        
};

除了 Observer 接口之外,RxJava 还内置了一个实现了 Observer 的抽象类:Subscriber。 Subscriber 对 Observer 接口进行了一些扩展,但他们的基本使用方式是完全一样的.不仅基本使用方式一样,实质上,在 RxJava 的 subscribe 过程中,Observer 也总是会先被转换成一个 Subscriber 再使用。所以如果你只想使用基本功能,选择 Observer 和 Subscriber 是完全一样的。它们的区别对于使用者来说主要有两点:

  1. onStart(): 这是 Subscriber 增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行), onStart() 就不


    RxJava观察者模式关系图

    适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用 doOnSubscribe() 方法,具体可以在后面的文中看到。

  2. unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。

创建 ObservableRxJava2中的创建方法

RxJava观察者模式关系图
Observable.create(new ObservableOnSubscribe() {           
   @Override            
  public void subscribe(@NonNull ObservableEmittere) throws Exception {
          e.onNext("Hello");                
          e.onNext("World");            
  }        
});   

create方法接收一个ObservableOnSubscribe对象,会返回一个Observable对象,通过源码发现返回的Observable是他的实现类ObservableCreate,该类实现了subscribeActual方法,在该方法中调用了ObservableOnSubscribe对象的subscribe方法,因此当Observable被订阅的时候subscribe方法就会被触发,事件序列就会按在subscribe方法中写定的顺序调用.这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。create() 方法是 RxJava 最基本的创造事件序列的方法。基于这个方法, RxJava 还提供了一些方法用来快捷创建事件队列,例如:

  • just(T...) 将传入的参数依次发送出来。
    Observable.just("1", "2", "3"); //just方法中返回了ObservableFromArray这个Observable的子类对象 //他会依次调用onNext("1"),onNext("2"),onNext("3")
  • fromIterable(Iterablesource), fromArray(T... items) : 将传入的数组或 Iterable 拆分成具体对象后,依次发送出来。
String[] words = {"1", "2", "3"};        
Observable.fromArray(words);        
List list = new ArrayList<>();        
list.add("1");        
list.add("2");        
list.add("3");        
Observable.fromIterable(list);                

Subscribe订阅创建了 Observable 和 Observer 之后,再用 subscribe() 方法将它们联结起来observable.subscribe(mObserver);subscribe的源码如下:

@Override    
public final void subscribe(Observer observer) {        
    ObjectHelper.requireNonNull(observer, "observer is null");        
    try {            
    observer = RxJavaPlugins.onSubscribe(this, observer);                        
    ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");            
    subscribeActual(observer);       
     } catch (NullPointerException e) { // NOPMD          
        throw e;        
    } catch (Throwable e) {            
    Exceptions.throwIfFatal(e);            // can't call onError because no way to know if a Disposable has been set or not            
    // can't call onSubscribe because the call might have set a Subscription already            
    RxJavaPlugins.onError(e);            
    NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");            
    npe.initCause(e);            
    throw npe;        
    }    
}

会调用抽象方法subscribeActual, 由子类实现,事件序列就会按实现的subscribeActual按指定的顺序执行.整个过程中的关系如下图:

RxJava订阅过程图
除了 subscribe(Observer) 和 subscribe(Subscriber) ,subscribe() 还支持不完整定义的回调 subscribe(ConsumeronNext, ConsumeronError, Action onComplete, ConsumeronSubscribe)
示例代码如下:

ConsumeronNext = new Consumer() {
            @Override
            public void accept(@NonNull String s) throws Exception {
            }
        };        
ConsumeronError = new Consumer() {
            @Override
            public void accept(@NonNull Throwable t) throws Exception {
            }
        };        
Action onCompleted = new Action() {
            @Override
            public void run() throws Exception {
            }
        };        
ConsumeronSubscribe = new Consumer() {
            @Override
            public void accept(@NonNull Disposable disposable) throws Exception {
            }
        };
        observable.subscribe(onNext, onError, onCompleted, onSubscribe);

Consumer和Action是RxJava2.0版本后出现的接口,是为了替代1.X版本中的Action0,Action1等接口.其中,Action0 改名成Action,Action1改名成Consumer,而Action2改名成了BiConsumer,而Action3 - Action9都不再使用了,ActionN变成了Consumer。Action接口只有一个方法run(),该方法无参数无返回值,由于 onCompleted() 方法也是无参无返回值的,因此 Action 可以被当成一个包装对象,将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。这样其实也可以看做将 onCompleted() 方法作为参数传进了 subscribe()。Consumer 也是一个接口,它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;与 Action 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,因此 Consumer 可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。RxJava可以使用Consumer这种形式的接口用来包装不同的无返回值的方法.

简单示例

将字符串数组 words 中的所有字符串依次打印出来:

String[] words = {"1", "2", "3"};
       Observable.fromArray(words)
               .subscribe(new Consumer() {
                   @Override
                   public void accept(@NonNull String s) throws Exception {
                       Log.d("onNext", s);
                   }
               });

如上,使用的时候创建出Observable和Subscriber,再通过subscribe()方法串联起来,一次使用就完成了.但是,在 RxJava 的默认规则中,事件的发出和消费都是在同一个线程的。也就是说,如果只用上面的方法,实现出来的只是一个同步的观察者模式。观察者模式本身的目的就是『后台处理,前台回调』的异步机制,因此异步对于 RxJava 是至关重要的。而要实现异步,则需要用到 RxJava 的另一个概念: Scheduler 。

线程控制

—— Scheduler 在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。

Scheduler 的 使用

在RxJava 中,Scheduler ——调度器,相当于线程控制器,RxJava 通过它来指定每一段代码应该运行在什么样的线程。RxJava 已经内置了几个 Scheduler ,它们已经适合大多数的使用场景:- Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。

  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • Schedulers.single() 单线程,适用于需要在同一线程强顺序执行事件的场景
  • Schedulers.trampoline() 事件队列在一个参与线程中以FIFO方式工作并执行他们.
  • 另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。有了这几个 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。 * subscribeOn(): 指定 subscribe() 所发生的线程,即事件产生的线程。 * observeOn(): 指定 Subscriber 所运行在的线程。或者叫做事件消费的线程,即观察者回调方法执行的线程。
        String[] words = {"1", "2", "3"};
        Observable.fromArray(words)
                .subscribeOn(Schedulers.io())  //指定 subscribe() 发生在 IO 线程
                .observeOn(AndroidSchedulers.mainThread())  //指定 Subscriber 的回调发生在主线程
                .subscribe(new Consumer() {
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        Log.d("onNext", s);
                    }
                });

上面这段代码中,由于 subscribeOn(Schedulers.io()) 的指定,被创建的事件的内容 1、2、3、4 将会在 IO 线程发出;而由于 observeOn(AndroidScheculers.mainThread()) 的指定,因此 subscriber 数字的打印将发生在主线程 。事实上,这种在 subscribe() 之前写上两句 subscribeOn(Scheduler.io()) 和 observeOn(AndroidSchedulers.mainThread()) 的使用方式非常常见,它适用于多数的 『后台线程取数据,主线程显示』的程序策略。通过给定的图片Url获取到Bitmap,并将bitmap显示在ImageView中,示例如下:

        final String url;
        final ImageView imageView;
        Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(@NonNull ObservableEmittere) throws Exception {
               Bitmap bitmap = getBitmapFromUrl(url);
                e.onNext(bitmap);
                e.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                    }
                    @Override
                    public void onNext(@NonNull Bitmap bitmap) {
                        imageView.setImageBitmap(bitmap);
                    }
                    @Override
                    public void onError(@NonNull Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                    }
                });

getBitmapFromUrl方法为假方法,需要自己实现.这样通过Url获取Bitmap的过程将在子线程执行,而显示bitmap则会在主线程执行.

Scheduler 的原理

了解RxJava的线程调度需要从 subscribeOn和observeOn的源码着手.

subscribeOn解析

下面是subscribeOn的源码:

      public final ObservablesubscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
    }

返回的是ObservableSubscribeOn类的实例对象,ObservableSubscribeOn是对Observable的包装类,接收ObservableSource参数,而Observable本身是对ObservableSource的实现.

    public final class ObservableSubscribeOnextends AbstractObservableWithUpstream{
        //保存线程调度器
        final Scheduler scheduler;
        public ObservableSubscribeOn(ObservableSourcesource, Scheduler scheduler) {
            //super()只是简单的保存ObservableSource
            super(source);
            this.scheduler = scheduler;
        }
        @Override
        public void subscribeActual(final Observers) {
            //1  创建一个包装Observer
            final SubscribeOnObserverparent = new SubscribeOnObserver(s);
            //2  手动调用 下游(终点)Observer.onSubscribe()方法,所以onSubscribe()方法执行在 订阅处所在的线程
            s.onSubscribe(parent);
            //3 setDisposable()是为了将子线程的操作加入Disposable管理中
            parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
                @Override
                public void run() {
                //4 此时已经运行在相应的Scheduler 的线程中
                    source.subscribe(parent);
                }
            }));
        }
ObservableSubscribeOn是一个包装类,继承自AbstractObservableWithUpstream,内部实现了SubscribeOnObserver类,SubscribeOnObserver实现了Observer和Disposable接口.
    static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {
        private static final long serialVersionUID = 8094547886072529208L;
        //真正的下游(终点)观察者
        final Observeractual; //用于保存上游的Disposable,以便在自身dispose时,连同上游一起dispose
        final AtomicReferences;
        SubscribeOnObserver(Observeractual) {
            this.actual = actual;
            this.s = new AtomicReference();
        }
        @Override
        public void onSubscribe(Disposable s) {
        //onSubscribe()方法由上游调用,传入Disposable。在本类中赋值给this.s,加入管理。
            DisposableHelper.setOnce(this.s, s);
        }
        @Override
        public void onNext(T t) {
            actual.onNext(t);
        }
        @Override
        public void onError(Throwable t) {
            actual.onError(t);
        }
        @Override
        public void onComplete() {
            actual.onComplete();
        }
        @Override
        public void dispose() {
        //取消订阅时,连同上游Disposable一起取消
            DisposableHelper.dispose(s);
            DisposableHelper.dispose(this);
        }
        @Override
        public boolean isDisposed() {
            return DisposableHelper.isDisposed(get());
        }
        //这个方法在subscribeActual()中被手动调用,为了将Schedulers返回的Worker加入管理
        void setDisposable(Disposable d) {
            DisposableHelper.setOnce(this, d);
        }
    }

scheduler.scheduleDirect(new Runnable()..)方法源码如下:

    /**
    * Schedules the given task on this scheduler non-delayed execution.
    * ....
.    */
    public Disposable scheduleDirect(Runnable run) {
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }

从注释和方法名我们可以看出,这个传入的Runnable会立刻执行。再继续往里面看:

    public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
        //class Worker implements Disposable ,Worker本身是实现了Disposable
          final Worker w = createWorker();
        //hook略过
        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
        //开始在Worker的线程执行任务,
        w.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                //调用的是 run()不是 start()方法执行的线程的方法。
                    decoratedRun.run();
                } finally {
                //执行完毕会 dispose()
                    w.dispose();
                }
            }
        }, delay, unit);
        //返回Worker对象
        return w;
    }

createWorker()是一个抽象方法,由具体的Scheduler类实现,例如IoScheduler对应的Schedulers.io().scheduler.scheduleDirect(new Runnable()..)的重点:

  • 传入的Runnable是立刻执行的。
  • 返回的Worker对象就是一个Disposable对象,
  • Runnable执行时,是直接手动调用的 run(),而不是 start()方法.这样处理应该是为了,能控制在run()结束后(包括异常终止),都会自动执行Worker.dispose().
  • 返回的Worker对象也会被parent.setDisposable(...)加入管理中,以便在手动dispose()时能取消线程里的工作。subscribeOn(Schedulers.xxx())的过程:
  1. 返回一个ObservableSubscribeOn包装类对象
  2. 上一步返回的对象被订阅时,回调该类中的subscribeActual()方法,在其中会立刻将线程切换到对应的Schedulers.xxx()线程。
  3. 在切换后的线程中,执行source.subscribe(parent);,对上游(终点)Observable订阅
  4. 上游(终点)Observable开始发送数据,根据RxJava2 源码解析(一),上游发送数据仅仅是调用下游观察者对应的onXXX()方法而已,所以此时操作是在切换后的线程中进行。
observeOn解析

observeOn方法源码

    public final ObservableobserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
    }

返回的是包装类ObservableObserveOn,查看该类源码

    public final class ObservableObserveOn extends AbstractObservableWithUpstream{
        final Scheduler scheduler;
        final boolean delayError;
        final int bufferSize;
        public ObservableObserveOn(ObservableSourcesource, Scheduler scheduler, boolean delayError, int bufferSize) {
            super(source);
            this.scheduler = scheduler;
            this.delayError = delayError;
            this.bufferSize = bufferSize;
        }
        @Override
        protected void subscribeActual(Observerobserver) {
            if (scheduler instanceof TrampolineScheduler) {
                source.subscribe(observer);
            } else {
            //根据观察的线程创建对应的Worker
                Scheduler.Worker w = scheduler.createWorker();//订阅上游数据源,
                //在ObserveOnObserver中处理
                source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
            }
        }

订阅的数据会到ObserveOnObserver对应的回调方法onXXX中处理.

    static final class ObserveOnObserver extends BasicIntQueueDisposable implements Observer, Runnable {
            //下游的观察者
            final Observeractual;
            //对应Scheduler里的Worker
            final Scheduler.Worker worker;
            //上游被观察者 push 过来的数据都存在这里
            SimpleQueuequeue;
            Disposable s;
            //如果onError了,保存对应的异常
            Throwable error;
            //是否完成
            volatile boolean done;
            //是否取消
            volatile boolean cancelled;
            // 代表同步发送 异步发送
            int sourceMode;
            ....
            @Override
            public void onSubscribe(Disposable s) {
                if (DisposableHelper.validate(this.s, s)) {
                    this.s = s;
                    //省略大量无关代码
                    //创建一个queue 用于保存上游 onNext() push的数据
                    queue = new SpscLinkedArrayQueue(bufferSize);
                    //回调下游观察者onSubscribe方法
                    actual.onSubscribe(this);
                }
            }
            @Override
            public void onNext(T t) {
                //1 执行过error / complete 会是true
                if (done) {
                    return;
                }
                //2 如果数据源类型不是异步的, 默认不是
                if (sourceMode != QueueDisposable.ASYNC) {
                    //3 将上游push过来的数据 加入 queue里
                    queue.offer(t);
                }
                //4 进行线程调度,开始进入对应Workder线程,在线程里 将queue里的t 取出 发送给下游Observer
                schedule();
            }
            @Override
            public void onError(Throwable t) {
                //已经done 会 抛异常 和 上一篇文章里提到的一样
                if (done) {
                    RxJavaPlugins.onError(t);
                    return;
                }
                //给error存个值
                error = t;
                done = true;
                //开始调度
                schedule();
            }
            @Override
            public void onComplete() {
            //已经done 会 返回  不会crash 和上一篇文章里提到的一样
                if (done) {
                    return;
                }
                done = true;
                //开始调度
                schedule();
            }
            void schedule() {
                if (getAndIncrement() == 0) {
                    //该方法需要传入一个线程, 注意看本类实现了Runnable的接口,会执行本类的run()方法
                    worker.schedule(this);
                }
            }
            //由于本类实现了Runable, 在schedule()方法中对本类的run方法通过worker进行了调度,因此从这里开始,这个方法已经是在Workder对应的线程里执行的了
            @Override
            public void run() {
                //默认是false
                if (outputFused) {
                    drainFused();
                } else {
                    //取出queue里的数据 发送
                    drainNormal();
                }
            }
            void drainNormal() {
                int missed = 1;
                final SimpleQueueq = queue;
                final Observera = actual;
                for (;;) {
                    // 1 如果已经 终止 或者queue空,则跳出函数,
                    if (checkTerminated(done, q.isEmpty(), a)) {
                        return;
                    }
                    for (;;) {
                        boolean d = done;
                        T v;
                        try {
                            //2 从queue里取出一个值
                            v = q.poll();
                        } catch (Throwable ex) {
                            //3 异常处理 并跳出函数
                            Exceptions.throwIfFatal(ex);
                            s.dispose(); 
                           q.clear();
                            a.onError(ex);
                            return;
                        }
                        boolean empty = v == null;
                        //4 再次检查 是否 终止  如果满足条件 跳出函数
                        if (checkTerminated(d, empty, a)) {
                            return;
                        } 
                       //5 上游还没结束数据发送,但是这边处理的队列已经是空的,不会push给下游 Observer
                        if (empty) {
                            //仅仅是结束这次循环,不发送这个数据而已,并不会跳出函数
                            break;
                        }
                        //6 发送给下游了
                        a.onNext(v);
                    }
                    //7 对应的线程安全的操作,本类实现了 AtomicInteger,addAndGet方法是 以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果
                    missed = addAndGet(-missed);
                    if (missed == 0) {
                        break;
                    }
                }
            }
            //检查 是否 已经 结束(error complete), 是否没数据要发送了(empty 空),  
          boolean checkTerminated(boolean d, boolean empty, Observera) {
                //如果已经disposed
                if (cancelled) {
                    queue.clear();
                    return true;
                }
                // 如果已经结束
                if (d) {
                    Throwable e = error;
                    //如果是延迟发送错误
                    if (delayError) {
                        //如果空
                        if (empty) {
                            if (e != null) {
                                a.onError(e);
                            } else {
                                a.onComplete();
                            }
                            //停止worker(线程)
                            worker.dispose();
                            return true;
                        }
                    } else {
                        //发送错误
                        if (e != null) {
                            queue.clear();
                            a.onError(e);
                            worker.dispose();
                            return true;
                        } else
                        //发送complete
                        if (empty) {
                            a.onComplete();
                            worker.dispose();
                            return true;
                        }
                    }
                }
                return false;
            }
        }
  1. ObserveOnObserver实现了Observer和Runnable接口。
  2. 在onNext()里,先不切换线程,将数据加入队列queue。然后开始切换线程,在另一线程中,从queue里取出数据,push给下游Observer
  3. onError() onComplete()也是将错误/完成信息先保存,切换线程后再发送。
  4. 所以observeOn()影响的是其下游的代码,且多次调用仍然生效。
  5. 因为其切换线程代码是在Observer里onXXX()做的,这是一个主动的push行为(影响下游)。
  6. 关于多次调用生效问题。对比subscribeOn()切换线程是在subscribeActual()里做的,只是主动切换了上游的订阅线程,从而影响其发射数据时所在的线程。而直到真正发射数据之前,任何改变线程的行为,都会生效(影响发射数据的线程)。所以subscribeOn()只生效一次。observeOn()是一个主动的行为,并且切换线程后会立刻发送数据,所以会生效多次.### 操作符 变换#### map操作符示例代码:源头Observable发送的是String类型的数字,利用map转换成int型,最终在终点Observer接受到的也是int类型数据。:
        final ObservabletestCreateObservable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmittere) throws Exception {
                e.onNext("1");
                e.onComplete() 
           }
        });
                    Observablemap = testCreateObservable.map(new Function() {
                @Override
                public Integer apply(String s) throws Exception {
                    return Integer.parseInt(s);
                }
            });
            map.subscribe(new Observer() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(TAG, "onSubscribe() called with: d = [" + d + "]");
                }
               @Override
                public void onNext(Integer value) {
                    Log.d(TAG, "onNext() called with: value = [" + value + "]");
                }
                @Override
                public void onError(Throwable e) {
                    Log.d(TAG, "onError() called with: e = [" + e + "]");
                }
                @Override
                public void onComplete() {
                    Log.d(TAG, "onComplete() called");
                }
            });

进入到map()函数的源码中

      public finalObservablemap(Functionmapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));
    }

返回的是ObservableMap,看ObservableMap的源码

    public final class ObservableMap extends AbstractObservableWithUpstream{
        //将function变换函数类保存起来
        final Functionfunction;
        public ObservableMap(ObservableSourcesource, Functionfunction) {
            //super()将上游的Observable保存起来 ,用于subscribeActual()中用。
            super(source);
            this.function = function;
        }
        @Override
        public void subscribeActual(Observert) {
            source.subscribe(new MapObserver(t, function));
        }

它继承自AbstractObservableWithUpstream,该类继承自Observable,很简单,就是将上游的ObservableSource保存起来,做一次wrapper,所以它也算是装饰者模式的体现.关于ObservableSource,所有的Observable都实现了它,所以我们可以认为Observable和ObservableSource是同等的.ObservableMap中还将Function保存起来,Function的定义超级简单,就是一个接口,给我一个T,还你一个R.

    public interface Function
{        R apply(T t) throws Exception;
    }

subscribeActual是真正订阅发生的地方,通过源码发现订阅的是内部类MapObserver,其实现如下:

    static final class MapObserver extends BasicFuseableObserver{

final Function mapper;

MapObserver(Observer actual, Function mapper) {

//super()将actual保存起来

super(actual);

//保存Function变量

this.mapper = mapper;

}

@Override

public void onNext(T t) {

//done在onError 和 onComplete以后才会是true,默认这里是false,所以跳过

if (done) {

return;

}

//默认sourceMode是0,所以跳过

if (sourceMode != NONE) {

actual.onNext(null);

return;

}

//下游Observer接受的值

U v;

//这一步执行变换,将上游传过来的T,利用Function转换成下游需要的U。

try {

v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");

} catch (Throwable ex) {

fail(ex);

return;

}

//变换后传递给下游Observer

actual.onNext(v);

}

你可能感兴趣的:(RxJava的简介和使用)