RxJava使用心得记录

1、RxJava链式调用步骤:

      如 Observable.just("123").map():

map:最后封装成ObservableMap返回(当然肯定是Observable的子类),最后调用subscribe的时候,会最终调用        ObservableMap的subscribeActual方法(实际上每个Observable子类最终都会调用subscribeActual方法),如下面代码。

public void subscribeActual(Observer<? super U> t) {
    source.subscribe(new MapObserver<T, U>(t, function));
}

在ObservableMap的subscribeActual方法中会调用上一层的subscribe,上一层就是 调用map的 那个对象,然后一层一层subscribe上去。

ObservableJust主要代码如下,调用subscribe后当然最终还是调用subscribeActual方法,如下

protected void subscribeActual(Observer<? super T> observer) {
    ScalarDisposable<T> sd = new ScalarDisposable<T>(observer, value);
    observer.onSubscribe(sd);
    sd.run();
}

又封装了一个ScalarDisposable对象,把observer传递进去,这里的observer,对于ObservableMap来说就是MapObserver,然后可以在 run方法里面看到对observer的调用,如下

public void run() {
    if (get() == START && compareAndSet(START, ON_NEXT)) {
        observer.onNext(value);
        if (get() == ON_NEXT) {
            lazySet(ON_COMPLETE);
            observer.onComplete();
        }
    }
}

调用observer的onNext方法,这方法,其实就会调用ObservableMap.MapObserver的onNext方法,因为在ObservableMap封装了一个叫MapObserver的Observer传递进去,这样又一层一层的通过调用Observer的方法,最终执行回调 Consumer.accept。

这里注意MapObserver.onNext里面有执行对参数的变换,因为 有个Function转换过程,将转换后的结果用作下一层的onNext参数调用。

其实RxJava的大致逻辑就是这样,对于线程变换其实也差不多。

2、线程变换observerOn。

同样也是封装了一个Observable的子类ObservableObserveOn,在subscribeActual里面又封装了一个叫ObserveOnObserver的 Observer,同样找到onNext方法,如下:

public void onNext(T t) {
    if (done) {
        return;
    }

    if (sourceMode != QueueDisposable.ASYNC) {
        queue.offer(t);
    }
    schedule();
}

这里有个异步步骤,就是想把参数offer到队列,然后调用schedule启动线程(基本上都是通过线程池),当然启动线程后在run里面找对应执行,如下

@Override
public void run() {
    if (outputFused) {
        drainFused();
    } else {
        drainNormal();
    }
}

正常逻辑下当然走drainNormal,代码如下

void drainNormal() {
    int missed = 1;

    final SimpleQueue<T> q = queue;
    final Observer<? super T> a = downstream;

    for (;;) {
        if (checkTerminated(done, q.isEmpty(), a)) {
            return;
        }

        for (;;) {
            boolean d = done;
            T v;

            try {
                v = q.poll();
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                disposed = true;
                upstream.dispose();
                q.clear();
                a.onError(ex);
                worker.dispose();
                return;
            }
            boolean empty = v == null;

            if (checkTerminated(d, empty, a)) {
                return;
            }

            if (empty) {
                break;
            }

            a.onNext(v);
        }

        missed = addAndGet(-missed);
        if (missed == 0) {
            break;
        }
    }
}

里面也有个onNext,这里是调用下一级的onNext,run方法里面调用下一层的onNext当然对下一层实现了线程变换。

3、线程变换之subscribeOn

之前有看到别人说 subscribeOn调用,会对最近上一次的线程变换,其实不是,subscribeOn调用,其实是对第一层的 线程变换,还是以ObservableMap为例,看看subscribeActual方法

public void subscribeActual(Observer<? super U> t) {
  source.subscribe(new MapObserver<T, U>(t, function));
}

这个方法里面MapObserver订阅了source(这里有点绕,感觉是source订阅了MapObserver),先不管谁订阅谁,其实简单来说就是source跟MapObserver建立了关系,后面最顶层source的subscribeActual会调用MapObserver的onNext方法。

但是我们可以看到subscribeOn的参数是ObservableSubscribeOn,当然这个ObservableSubscribeOn也是Observable的子类,那么肯定有subscribeActual方法,看看这个方法:

 

public void subscribeActual(final Observer<? super T> observer) {
    final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);

    observer.onSubscribe(parent);

    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}

你会发现一个问题,没有source.subscribe()的调用(这个方法其实不管是在map、flatMap、observableMap里面都有这样的调用),如果没有这个调用的话,就不能跟上层建立关系,那么上层就没法调用当前Observer的onNext方法,肯定是不对的,再找找,你会发现在这个类下面有个内部类 SubscribeTask,这个的 run方法里面有这个source.subscribe(parent),source其实就是上一层,他把subscribeActual里面的source.subscribe()放到了这个内部类里面的 run方法里面了,再看看SubscribeTask实现了Runnable接口,那么基本上就明了了,订阅关系是在 线程里面发生的,简单来说就是 subscribeOn前面的订阅关系 其实都是在subscribeOn所在的线程里面发生的,当然肯定直接反应到 第一层的Observable。第一层Observable调用subscribeActual时会调用下一层Observer的onNext方法,那么这个onNext方法肯定就是在subscribeOn所在的线程里面,至于后面的onNext方法有observerOn,所以如果有onserverOn的话,就会切换到其所在线程。

 

说明:本篇文章仅供自己记录,若有幸让其他人看到,写的不是很详细请多包涵,也请多扶正。谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值