RxJava称为响应式编程
RxJava也称为异步事件流编程
线程的切换很重要
一.subscribeOn 给上面代码分配线程
.subscribeOn(
Schedulers.io() // 耗时读取的异步
)
1.先分析Schedulers.io() 和它的hook
@NonNull
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
return RxJavaPlugins.onIoScheduler(IO); 又是一个hook
@NonNull
public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
Function<? super Scheduler, ? extends Scheduler> f = onIoHandler;
if (f == null) {
return defaultScheduler;
}
return apply(f, defaultScheduler);
}
查看 onIoHandler 唯一被赋值的地方:
public static void setIoSchedulerHandler(@Nullable Function<? super Scheduler, ? extends Scheduler> handler) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
onIoHandler = handler;
}
hook代码:
// TODO Hook IO 传递进去的Hook
RxJavaPlugins.setIoSchedulerHandler(new Function<Scheduler, Scheduler>() {
@Override
public Scheduler apply(Scheduler scheduler) throws Exception {
Log.d(L.TAG, "apply: 全局监听scheduler:" +scheduler);
return scheduler;
}
});
查看分析IO:
@NonNull
static final Scheduler IO;
static {
SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());
COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());
IO = RxJavaPlugins.initIoScheduler(new IOTask());
TRAMPOLINE = TrampolineScheduler.instance();
NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
}
IO = RxJavaPlugins.initIoScheduler(new IOTask());
IO 的实例化中又来了hook:
@NonNull
public static Scheduler initIoScheduler(@NonNull Callable<Scheduler> defaultScheduler) {
ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null");
Function<? super Callable<Scheduler>, ? extends Scheduler> f = onInitIoHandler;
if (f == null) {
return callRequireNonNull(defaultScheduler);
}
return applyRequireNonNull(f, defaultScheduler);
}
onInitIoHandler 只有一个地方可以赋值:
public static void setInitIoSchedulerHandler(@Nullable Function<? super Callable<Scheduler>, ? extends Scheduler> handler) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
onInitIoHandler = handler;
}
hook代码:
// TODO hook 给 IO 初始化
RxJavaPlugins.setInitIoSchedulerHandler(new Function<Callable<Scheduler>, Scheduler>() {
@Override
public Scheduler apply(Callable<Scheduler> schedulerCallable) throws Exception {
Log.d(L.TAG, "apply: 全局监听 init scheduler:" +schedulerCallable.call());
return schedulerCallable.call();
}
});
2.第一步分析 .io() 和 .newThread()
Schedulers.io() 一执行 返回的就是Scheduler IO;
IO = RxJavaPlugins.initIoScheduler(new IOTask());
new IOTask()
Schedulers 策略机制 IO是一种
Schedulers 策略最终用线程池完成
策略:
Schedulers.io() : 耗时读取的异步
Schedulers.newThread() : 开启新线程异步
Schedulers.io() 耗时读取的异步策略 是用 new IOTask() 完成的
Schedulers.newThread() 开启新线程异步 是用 new NewThreadTask() 完成的
查看IOTask:
static final class IOTask implements Callable<Scheduler> {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
}
静态内部类,实现了Callable,有返回值的任务
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
返回一个IoScheduler()
查看IoScheduler()
public IoScheduler() {
this(WORKER_THREAD_FACTORY);
}
public IoScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<CachedWorkerPool>(NONE);
start();
}
@Override
public void start() {
CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
void shutdown() {
allWorkers.dispose();
if (evictorTask != null) {
evictorTask.cancel(true);
}
if (evictorService != null) {
evictorService.shutdownNow();
}
}
private final ScheduledExecutorService evictorService;
线程池
public interface ScheduledExecutorService extends ExecutorService {...}
.subscribeOn(
// TODO 第一步 到底干了什么 ( new IOScheduler ---> 线程池)
Schedulers.io() // 耗时读取的异步
// Schedulers.newThread() // 开启新线程
)
查看NewThreadTask:
static final class NewThreadTask implements Callable<Scheduler> {
@Override
public Scheduler call() throws Exception {
return NewThreadHolder.DEFAULT;
}
}
静态内部类,实现了Callable,有返回值的任务
static final class NewThreadHolder {
static final Scheduler DEFAULT = new NewThreadScheduler();
}
返回一个NewThreadScheduler()
3.第二步分析.subscribeOn()
IoScheduler()传进去
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
IoScheduler()存在这里
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
// ObservbaleCreate.subscribeOn
// TODO 第二步 new IOScheduler ---> 线程池 传递进去
.subscribeOn(
// TODO 第一步 到底干了什么 ( new IOScheduler ---> 线程池)
Schedulers.io() // 耗时读取的异步
// Schedulers.newThread() // 开启新线程
)
// A线程. subscribe
// ObservableSubscribeOn.subscribe
.subscribe(自定义观察者);
ObservableSubscribeOn.subscribe()
进入到ObservableSubscribeOn的subscribeActual函数中
s是终点 包装成SubscribeOnObserver包裹1
@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)));
}
parent就是我们的包裹1
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当中source.subscribe(parent);
调用了ObservableCreate里面的CreateEmitter封装成包裹2
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
source.subscribe(parent); 自定义source
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
.....
}
final Scheduler scheduler = IoScheduler(线程池的)
ObservableSubscribeOn 里面的subscribeActual
@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)));
}
scheduler.scheduleDirect(new SubscribeTask(parent))
IoScheduler(线程池的).scheduleDirect(new SubscribeTask(parent))
scheduleDirect函数:
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
@NonNull
public abstract Worker createWorker();
createWorker的创建丢给子类
IoScheduler.createWorker(){new EventLoopWorker(pool.get();}
查看其在IoScheduler里面的子类
@NonNull
@Override
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
把EventLoopWorker类创建出来
继续查看抽象类Scheduler的scheduleDirect
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
decoratedRun就是红色的Runnable
交给DisposeTask任务,其又是一个Runnable 做到中断
static final class DisposeTask implements Runnable, Disposable {
final Runnable decoratedRun;
final Worker w;
Thread runner;
DisposeTask(Runnable decoratedRun, Worker w) {
this.decoratedRun = decoratedRun;
this.w = w;
}
...
}
把最后封装好的Runnable 丢给w
w是new EventLoopWorker(pool.get(); new好的对象
w.schedule(task, delay, unit); 就调用到EventLoopWorker类里面的schedule去了
@NonNull
@Override
public Disposable schedule(@NonNull Runnable action) {
if (disposed) {
return EmptyDisposable.INSTANCE;
}
return poolWorker.scheduleActual(action, 0, TimeUnit.MILLISECONDS, serial);
}
又丢给scheduleActual
@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;
}
executor.submit((Callable)sr) 最后丢给了线程池
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
SubscribeTask(parent)任务一执行就会处于异步
整块都是异步
source 异步线程
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
自定义观察者中的onSubscribe是不参与线程转换的,还是主线程
@Override
public void onSubscribe(Disposable d) {
Disposable disposable = d;
}
终点是不能是异步线程的,我们要在终点更新UI ↓
二.observeOn 给下面代码分配线程
// TODO 第二步骤
.observeOn(
// TODO 第一步 拿到主线程的 Handlnr
AndroidSchedulers.mainThread()
)
1.第一步分析 AndroidSchedulers.mainThread()
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
new Callable<Scheduler>() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
最后是通过handler切换主线程的
new Handler(Looper.getMainLooper()) Looper放进去保证100%一定是主线程
传进去的handler100%主线程
private final Handler handler;
HandlerScheduler(Handler handler) {
this.handler = handler;
}
HandlerScheduler的createWorker
@Override
public Worker createWorker() {
return new HandlerWorker(handler);
}
然后就是HandlerScheduler$.HandlerWorker
HandlerScheduler的内部类HandlerWorker
schedule{
......
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
......
}
AndroidSchedulers.mainThread()
这一句话就是拿到了主线程的handler
2.第二步分析 .observeOn()
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
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));
}
scheduler 是主线程handler的 scheduler
查看ObservableObserveOn
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;
}
......
}
ObservableObserveOn里面存放一份主线程handler的scheduler
@Override
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));
}
}
if (scheduler instanceof TrampolineScheduler)
如果线程相同则不用干活
如果线程不同就先打包裹
new ObserveOnObserver(observer, w, delayError, bufferSize)
订阅是observeOn()返回的类ObservableObserveOn点出来的
ObservableObserveOn.subscribe
在ObservableObserveOn里面的subscribeActual函数里面打包第一个包裹1 ObserveOnObserver
在上一层是ObservableCreate
…
最后返回到ObserveOnObserver里面的onNext是会把任务交给handler
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
schedule();之上是子线程,schedule();执行后就交给handler变成主线程了
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
逻辑图
subscribeOn()切换线程时序图
observeOn()时序图
Scheduler分类
补充
// subsceOn(1) // 会显示是这个线程的原因,上一层卡片是被1线程执行
// subsceOn(2)
// subsceOn(3)
// observeOn(A)
// observeOn(B)
// observeOn(C) // 终点是被C执行