RxJava线程切换与自定义操作符

内容:

  • 线程切换原理
  • 自定义RxView操作符

第三节课难度曲线

在这里插入图片描述

线程切换原理

分析RxJava线程切换原理。

subscribeOn 给上面代码分配线程

        Observable.create(

                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        e.onNext("subscribe");

                        Log.d(L.TAG, "自定义source: thread=" + Thread.currentThread().getName());
                    }
        })

        // ObservbaleCreate.subscribeOn
        // TODO 第二步     new IOScheduler ---> 线程池 传递进去,执行subscribe()后线程池才真正执行任务
        .subscribeOn(

                // TODO 第一步  到底干了什么 ( new IOScheduler ---> 内部封装了线程池 )
                Schedulers.io() // 耗时读取的异步

                // Schedulers.newThread() // 开启新线程

        )

        //.subscribeOn(AndroidSchedulers.mainThread()) // AndroidSchedulers是rxandroid特有的Schedulers


         // A线程.subscribe,因为这里没切线程,所以就是main线程调用的subscribe,所以onSubscribe是在main线程调用的
         // ObservableSubscribeOn.subscribe
        .subscribe(

                // 终点
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                        Disposable disposable = d;
                        Log.d(L.TAG, "onSubscribe: thread=" +  Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(L.TAG, "onNext: thread=" + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
        });

流程图:
当调用subscribe时,即在外面包裹一层包裹,每一层包裹又会继续调用subscribe继续包裹一层包裹,直到最顶层时起点source的subscribe会执行onNext()进行一层一层往下拆包裹。
在这里插入图片描述

Schedulers.io():
在这里插入图片描述

Schedulers.io()最终是创建了IoScheduler对象,里面维护着CachedWorkerPool对象,CachedWorkerPool就是一个Runnable对象。

public final class IoScheduler extends Scheduler {

	...
	
    static final class CachedWorkerPool implements Runnable {
        private final long keepAliveTime;
        private final ConcurrentLinkedQueue<ThreadWorker> expiringWorkerQueue;
        final CompositeDisposable allWorkers;
        private final ScheduledExecutorService evictorService;
        private final Future<?> evictorTask;
        private final ThreadFactory threadFactory;

	...


}

subscribeOn()切换线程时序图:
在这里插入图片描述
subscribeOn():

//Observable.java

    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

new 了一个ObservableSubscribeOn对象包装scheduler:

//ObservableSubscribeOn.java
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }

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

        s.onSubscribe(parent);

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

	...
}

即subscribeOn(Scheduler scheduler)返回的是一个ObservableSubscribeOn对象。

ObservableSubscribeOn 是 Observable的子类

后续调用 .subscribe()时就是调用Observable的subscribe(因为ObservableSubscribeOn 没有重写subscribe):

//Observable.java

    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

            subscribeActual(observer);
        }
        
        ...
    }

subscribeActual是abstract函数,实现类是Observable的子类ObservableSubscribeOn:

//ObservableSubscribeOn.java

    @Override
    public void subscribeActual(final Observer<? super T> s) {
    	//先给s包裹了一层得到parent,这里的s就是终点Observer
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
		//先回调Observer的onSubscribe(),即调用终点Observer的onSubscribe
        s.onSubscribe(parent);
		//然后真正开始从上到下开始调用
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }

new SubscribeTask(parent),又用SubscribeTask包装了parent,看下SubscribeTask:

//ObservableSubscribeOn.java

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
	final Scheduler scheduler;
	    
	    ...
	    
    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            source.subscribe(parent);
        }
    }
}

SubscribeTask是给scheduler里面的线程池运行的。

即subscribe()都是在一层一层的包装包裹,直到最顶层的Observable.create,会调用ObservableOnSubscribe#subscribe通过ObservableEmitter的onNext进行拆包裹。

继续看scheduler.scheduleDirect(new SubscribeTask(parent))的scheduler.scheduleDirect:

//scheduler.java 
	//run就是SubscribeTask对象
    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        final Worker w = createWorker();//createWorker是子类实现的,比如IoScheduler

        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        DisposeTask task = new DisposeTask(decoratedRun, w);

        w.schedule(task, delay, unit);//调用的是IoScheduler的schedule

        return task;
    }
//IoScheduler.java

        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);
        }

threadWorker.scheduleActual:

//NewThreadWorker.java
    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;
    }

调用的是线程池的submit或者schedule。

通过上面的源码scheduler.scheduleDirect(new SubscribeTask(parent))分析,这句代码就是通过scheduleDirect()把SubscribeTask交给scheduler里面的线程池执行,看下执行的任务SubscribeTask :

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            source.subscribe(parent);
        }
    }

run()里面又会调用subscribe(),继续在包裹的外面继续包一层包裹,不断执行这个过程,直到最顶层裹时会调用onNext()进行往下拆包裹,执行各个函数。

observeOn 给下面代码分配线程

Observable.create(

                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        e.onNext("subscribe");

                        Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
                    }
                })

                // TODO 第二步骤
                .observeOn(

                        // TODO 第一步   主线程的 Handlnr
                        AndroidSchedulers.mainThread()

                )

                // subsceOn(1)  // 上面代码是在1线程执行的原因:上一层卡片是被1线程执行
                // subsceOn(2)
                // subsceOn(3)

                // observeOn(A)
                // observeOn(B)
                // observeOn(C) // 终点是在C线程执行


                // ObservableObserveOn.subscribe
                .subscribe(

                        // 终点
                        new Observer<String>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.d(L.TAG, "onSubscribe: " +  Thread.currentThread().getName());
                            }

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

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        }

AndroidSchedulers:
在这里插入图片描述
AndroidSchedulers.mainThread()就是HandlerScheduler:

public final class AndroidSchedulers {

    private static final class MainHolder {

        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }

    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });
            
            ...
}

就是创建了一个主线程Handler的Scheduler。

流程图:
在这里插入图片描述

observeOn()时序图:
在这里插入图片描述

//ObservableObserveOn.java
	...
    
    protected void subscribeActual(Observer<? super T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();

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

    static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    implements Observer<T>, Runnable {

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

            if (sourceMode != QueueDisposable.ASYNC) {
                queue.offer(t);
            }
            schedule();
        }
        
        ...
        
        void schedule() {
            if (getAndIncrement() == 0) {
                worker.schedule(this);
            }
        }

当往下拆包裹调用到ObserveOnObserver的onNext()时会调用schedule(),执行worker.schedule(this); 这个worker是HandlerWorker:

//HandlerScheduler.java
final class HandlerScheduler extends Scheduler {
	
	...

    private static final class HandlerWorker extends Worker {
        private final Handler handler;

        private volatile boolean disposed;

        HandlerWorker(Handler handler) {
            this.handler = handler;
        }

        @Override
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            if (run == null) throw new NullPointerException("run == null");
            if (unit == null) throw new NullPointerException("unit == null");

            if (disposed) {
                return Disposables.disposed();
            }

            run = RxJavaPlugins.onSchedule(run);

            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);

            Message message = Message.obtain(handler, scheduled);
            message.obj = this; // Used as token for batch disposal of this worker's runnables.

            handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));

            // Re-check disposed state for removing in case we were racing a call to dispose().
            if (disposed) {
                handler.removeCallbacks(scheduled);
                return Disposables.disposed();
            }

            return scheduled;
        }

        @Override
        public void dispose() {
            disposed = true;
            handler.removeCallbacksAndMessages(this /* token */);
        }

        @Override
        public boolean isDisposed() {
            return disposed;
        }
    }
    
    ... 
} 

使用主线程的Handler来执行Runnable对象,这样就任务切换到了主线程执行。

Scheduler分类

在这里插入图片描述

自定义RxView操作符

在这里插入图片描述

作业

RxJava 线程切换自己的理解,文字描述,详细过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值