RxAndroid切换线程是怎么实现的呢?

1. 如何使用Rxjava


导入包

  implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
   implementation 'io.reactivex.rxjava2:rxjava:2.1.12'

创建被观察者:

   //创建一个被观察者
     Observable<Integer> observable=  Observable.create(new ObservableOnSubscribe<Integer>() {

            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onComplete();
            }
        });

创建观察者

     //创建一个观察者
        Observer<Integer> observer=new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG,"onNext:"+integer);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.d(TAG,"onComplete:");
            }
        };

注册

     //注册
      observable.subscribe(observer);

然后在观察者中便拿到了上游发送的值

04-24 10:19:28.313 2497-2497/? D/MainActivity: onNext:1
04-24 10:19:28.313 2497-2497/? D/MainActivity: onNext:2
04-24 10:19:28.313 2497-2497/? D/MainActivity: onComplete:

到这里就完成了一个简单的RxJava的使用。

2. 线程切换


首先我们对观察者和被观察者所在的线程进行打印,看下各自分别所在线程。

04-24 10:26:58.079 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: observable:main
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:main
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:1
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:main
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:2
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onComplete:

通过日志可以看出来都是在主线程中操作。但是我们平常需要做耗时操作怎么办呢,那第一时间会想到创建一个线程就解决了,这样也是没毛病的,不过在使用Rxjava中,它已经帮我在这一块封装好了。

    //注册
        observable.subscribeOn(Schedulers.io())//将被观察者切换到io线程
                .observeOn(AndroidSchedulers.mainThread())//再将observer所在的线程切换到主线程
                .subscribe(observer);
04-24 10:44:08.514 8070-8137/com.example.a2018_3_14.rxdemo D/MainActivity: observable:RxCachedThreadScheduler-1
04-24 10:44:08.535 8070-8070/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:main
04-24 10:44:08.535 8070-8070/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:1

通过打印的日志看出来确实在observable所在的线程被切换到了一个新的线程中,由于 .observeOn(AndroidSchedulers.mainThread())调用之后又将下游接受到的事件线程切换到了主线程。
subscribeOn用于对被观察者的线程进行切换,当多次切换时,只有第一次有效,observeOn用于对观察者进行线程切换,可以多次切换。

3. 线程调度器如何工作可以实现线程的切换

首先分析下面的这段代码,找到如何实现订阅:
 //创建一个被观察者
        Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {

            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {

                emitter.onNext(1);
                Log.d(TAG, "observable:" + Thread.currentThread().getName());
                emitter.onComplete();
            }
        });

        //创建一个观察者
        Observer<Integer> observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "onNext:" + Thread.currentThread().getName());
                Log.d(TAG, "onNext:" + integer);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete:" + Thread.currentThread().getName());
                Log.d(TAG, "onComplete:");
            }
        };
        //注册
        observable.subscribeOn(Schedulers.io())//将被观察者切换到io线程
                .observeOn(AndroidSchedulers.mainThread())//将观察者切换到主线程
                .(observer);

在create方法中的返回值中调用了onAssembly这个方法,就是返回了一个ObservableCreate对象,ObservableCreate是继承了Observable。

 @SchedulerSupport(SchedulerSupport.NONE)
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");//判断空
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));//返回ObservableCreate对象
    }
@SuppressWarnings({ "rawtypes", "unchecked" })
    @NonNull
    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

然后看ObservableCreate这个类,在这个类中的subscribeActual有订阅的方法,这个方法是什么时候调的呢,是在Observable.subscribe()方法中,在subscrible中有这段代码 subscribeActual(observer);然而这个方法是一个抽象方法,而ObservableCreate就是它的实现类,ObservableCreate中的subscribeActual就是对应的实现方法。

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);//调用观察者的onSubscribe

        try {
            source.subscribe(parent);//调用ObservableOnSubscribe的subscribe
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

在subscribeActual方法内部,首先把observer用CreateEmitter封装了下,CreateEmitter是ObservableCreate的内部类,并且实现ObservableEmitter,当调用 emitter.onNext(1);时会调用CreateEmitter的onNext()方法,判断isDisposed()不为空,然后调用obser的onNext()方法,同理onError,onComplete一样

  @Override
        public void onNext(T t) {
            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }
observeOn()内部线程切换

首先看observeOn()的方法内部是怎么实现的:

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

在OnAssembly这个方法中最终返回ObservableObserveOn对象,ObservableObserveOn实现了Observable。在ObservableObserveOn的构造方法中将线程调度类作为参数传入

  public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

然后看ObservableObserveOn这个类的内部的subscribeActual这个方法中走的是else方法,createWorker在Scheduler 中是一个抽象方法,具体的实现在IoScheduler中,返回的是EventLoopWorker这个内部类,然后订阅。

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
   // 在源码中对TrampolineScheduler的解释Schedules work on the current thread but does not execute immediately. Work is put in a queue and executed after the current unit of work is completed.
   //调度任务不会再当前线程立即执行,任务会被放在一个队列里面在当前任务的单元完成后执行。主要看else方法
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();

            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }

然后接着看ObserveOnObserver这个内部类,ObserveOnObserver实现了Runnable,在内部的onNext方法中 调用了调度schedule()。

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

            if (sourceMode != QueueDisposable.ASYNC) {
                queue.offer(t);
            }
            schedule();//调度方法
        }

在schedule()方法中调用了EventLoopWorker的schedule方法,然后追到EventLoopWorker源码中看下做了什么,应该就能找到线程切换的具体实现。

void schedule() {
            if (getAndIncrement() == 0) {
                worker.schedule(this);
            }
        }

在EventLoopWorker的schedule方法中调用了threadWorker的scheduleActual方法

 @Override
        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }

            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }
    }

在scheduleActual的方法中,把ObserveOnObserver放入到了线程池中,这样就完成了线程的切换。

 @NonNull
    public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
        Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);

        if (parent != null) {
            if (!parent.add(sr)) {
                return sr;
            }
        }

        Future<?> f;
        try {
            if (delayTime <= 0) {
                f = executor.submit((Callable<Object>)sr);//线程池的方法
            } else {
                f = executor.schedule((Callable<Object>)sr, delayTime, unit);
            }
            sr.setFuture(f);
        } catch (RejectedExecutionException ex) {
            if (parent != null) {
                parent.remove(sr);
            }
            RxJavaPlugins.onError(ex);
        }

        return sr;
    }

然后最后看下ObserveOnObserver的run方法的实现,会执行drainNormal()方法,然后看下drainNormal()方法内部的实现。

    @Override
        public void run() {
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();//执行该方法,
            }
        }

在drainNormal内部调用observer的onNext()方法。该方法在io线程中执行

 void drainNormal() {
            int missed = 1;

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

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

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

                    try {
                        v = q.poll();
                    } catch (Throwable ex) {
                        Exceptions.throwIfFatal(ex);
                        s.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);//调用OnNext方法
                }

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

到这里就把observerOn的线程切换流程分析完了。subscribeOn()就不做具体的分析了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值