内容:
- 线程切换原理
- 自定义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 线程切换自己的理解,文字描述,详细过程。