ついにスレッド切り替えになりました
まず、ねじ山を切る方法の簡単なフローチャートを見てください
注:上記の青いメインプロセスでは、subscribeOn(Schedulers.io())、observeOn(AndroidSchedulers.mainThread())
ただし、subscribeOnとobserveOnはメインスレッドまたは子スレッドに渡すことができます
これは、RxJavaスレッドを柔軟に元に戻すための鍵です。
================================================== ==================
最初に見てください
subscribeOn(Schedulers.io())
これは2つの部分に分かれています
| ------ subscribeOn()はRunnable {run { source.subscribe(parent); } }を作成し、コアはsource.subscribe(parent)であり、Schedulers.io()によって作成されたスケジューラーに渡します。コール。
| ------ Schedulers.io()は、新しいスレッドを作成して使用するようにスケジュールするために使用されるスケジューラーを返します。
次に、subscribeOn()がどのように実装されているかを見てみましょう(構造はmapなどのデータ変換操作と同じです)
/**
* subscribeOn 核心是new ObservableSubscribeOn<T>(this, scheduler)
*/
@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));
}
ObservableSubscribeOn源码 ↓
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)));
}
static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
//...省略其他代码...
@Override
public void onNext(T t) {
actual.onNext(t);
}
}
//核心代码
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
}
上記のsubscribeActualに戻ると、コードは次のとおりです。
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)));
}
最初にSubscribeOnObserver <T>親を作成し、 それを新しいSubscribeTaskに渡します。
SubscribeTaskはRunnableを実装し、そのrunメソッドでsource.subscribe(parent)を実行します。
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
次に、このRunnableをスケジューラscheduler.scheduleDirect(new SubscribeTask(parent))に渡します。
スケジューラースケジューラーはどこにあるのか、Schedulers.ioフロントサブスクライブオン(スケジューラースケジューラー)が何を渡すかを覚えておいてください()。
次に、Schedulers.io()がどのように見えるかを見てください
//源码点进去就是这个
@NonNull
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
そして、RxJavaPlugins.onIoScheduler(IO)がソースコードをクリックして、返されたものがIOであることがわかりました。
@NonNull
public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
Function f = onIoHandler; //onIoHandler为null
return f == null?defaultScheduler:(Scheduler)apply(f, defaultScheduler);
}
IOとは何かがわかります
public final class Schedulers {
......
@NonNull
static final Scheduler IO;
static {
SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());
COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());
// IO 在这里初始化
IO = RxJavaPlugins.initIoScheduler(new IOTask());
TRAMPOLINE = TrampolineScheduler.instance();
NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
}
......
}
そしてRxJavaPlugins.initIoScheduler(new IOTask());最終的な戻り値はnew IOTask()の戻り値です。あなたは何と言いますか?
@NonNull
public static Scheduler initIoScheduler(@NonNull Callable<Scheduler> defaultScheduler) {
ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can\'t be null");
Function f = onInitIoHandler; //注释:onInitIoHandler为null
return f == null?callRequireNonNull(defaultScheduler):applyRequireNonNull(f, defaultScheduler);
}
所以 RxJavaPlugins.initIoSchedule → callRequireNonNull(defaultScheduler)(代码如下)
@NonNull
static Scheduler callRequireNonNull(@NonNull Callable<Scheduler> s) {
try {
//s
return (Scheduler)ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can\'t be null");
} catch (Throwable var2) {
throw ExceptionHelper.wrapOrThrow(var2);
}
}
所以 callRequireNonNull(defaultScheduler) → ObjectHelper.requireNonNull(代码如下)
public final class ObjectHelper {
public static <T> T requireNonNull(T object, String message) {
if (object == null) {
throw new NullPointerException(message);
}
return object; //注释 这个object就是s.call()
}
}
次に、s.callメソッドが何であるかを見てみましょう
static final class IOTask implements Callable<Scheduler> {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
}
μIoHolder.DEFAULT= new IoScheduler();
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
也就是说最终为:
Schedulers.io() = new IoScheduler();
最後に、Schedulerから継承されたIoSchedulerを取得しました
public final class IoScheduler extends Scheduler {
.........................省略代码.............................
}
このようにして、両方の部分があります。次に、それらがどのように呼ばれるかを見ていきます。
呼び出しが開始される場所は、次のコード行です。subscribeActualのscheduler.scheduleDirect(new SubscribeTask(parent))
まず、IoSchedulerにはscheduleDirect メソッドがないことがわかりまし た。これは、親クラスのスケジューラに実装されているためです。
public abstract class Scheduler {
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
注释: scheduler.scheduleDirect(new SubscribeTask(parent))先到这里
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
public abstract Worker createWorker();
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit
unit) {
核心代码 ↓ createWorker在Scheduler中是抽象方法具体实现在子类IoScheduler中
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
这里就是子类createWorker得到 Worker w 调用schedule
task就是subscribeOn创建的Runnable
↓
w.schedule(task, delay, unit);
return task;
}
}
public final class IoScheduler extends Scheduler {
注释:createWorker创建并返回了一个EventLoopWorker对象
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
↓
static final class EventLoopWorker extends Scheduler.Worker {
private final ThreadWorker threadWorker;
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get();
}
@NonNull
@Override
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull
TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
注释: threadWorker = pool.get(),
而pool.get()点进看到返回的是一个ThreadWorker
最终执行的是ThreadWorker.scheduleActual(action, delayTime, unit, tasks)
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
}
↓
static final class ThreadWorker extends NewThreadWorker {
private long expirationTime;
注释:但是在ThreadWorker 中并没有scheduleActual
这个方法是在其父类NewThreadWorker中
ThreadWorker(ThreadFactory threadFactory) {
super(threadFactory);
this.expirationTime = 0L;
}
public long getExpirationTime() {
return expirationTime;
}
public void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
}
}
以下のNewThreadWorkerソースコードを見てみましょう
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull
TimeUnit unit, @Nullable DisposableContainer parent) {
注释:这里将run 进行装饰封装最终传递到ScheduledRunnable sr中
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
Future<?> f;
try {
注释: sr在这里执行也,就是Runnable在这里执行
还记得Runnable的run执行的是啥不: source.subscribe(parent);
// @Override
// public void run() {
// source.subscribe(parent);
// }
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;
}
}
ここでは、新しいスレッドでsubscribeOn(Schedulers.io())を実行します。
実際、.subscribeが新しいスレッドで実行されることを除けば、flatMapやmapなどの他の操作と似ています。
注:最初のsubscribeOnのみが機能しますか?
上の図でわかるように、最初のsubscribeOnは新しいThread1を作成し、2番目のsubscribeOnは新しいThread2を作成します。
コールチェーンでは、最初に2番目のsubscribeOnを実行し、Thread2に切り替えて.subscribeメソッドを実行し、次に最初のsubscribeOnに切り替えてThread1に切り替えます。後続の.subscribeと.onNextは、どちらも最初のsubscribeOnによって作成されたThread1スレッドにあります。実施した。したがって、最初のsubscribeOnのみが機能し、後続のsubscribeOnは効果がないとは言えません。.subscribeメソッドが実行されます。。。(それも役に立たないようです)。
================================================== ==============
以下をご覧ください
observeOn(AndroidSchedulers.mainThread())
また、2つの部分に分かれています
| ------ observeOn()はRunnable {run {.onNext()}}も作成し、それをに渡します
AndroidSchedulers.mainThread()によって作成されたスレッドで呼び出されます。
| ------ AndroidSchedulers.mainThread()は、observeOnによって作成されたRunnableを実行するためのスレッドを返します。
最初に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));
}
↓
↓
↓ 接着看ObservableObserveOn
↓
↓
↓
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
注释:scheduler就是我们传进来的AndroidSchedulers.mainThread()
final Scheduler scheduler;
public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean
delayError, int bufferSize) {
super(source);
this.scheduler = 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));
}
}
}
Scheduler.Worker w = Scheduler.createWorker()ご存知かどうかを確認してください
source.subscribe(new ObserveOnObserver <T>(observer、w、delayError、bufferSize));ここに直接。コントロール。
次に、ObserveOnObserverを見てみましょう。onNextがスレッドを切り替えてデータを転送する方法
注意:ObserveOnObserver实现的了Runnable,
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
final Scheduler.Worker worker;
ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean
delayError, int bufferSize) {
this.worker = worker;
...
}
@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);
}
}
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
...
final Observer<? super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
......
a.onNext(v);
}
......
}
}
}
onNextでの実行はworker.schedule(this);です。
| ------ワーカー:scheduler.createWorker()
| ------これ:Runnableを実装するのはObserveOnObserver自体です
ここでobserveOnは終了し、ワーカーを見つける必要があるのはcreateWorkerの方法です。
次に、着信スケジューラ(実際には渡したAndroidSchedulers.mainThread)によって異なります。
AndroidSchedulers.mainThread()
public final class AndroidSchedulers {
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
↓
↓ RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD)返回的就是MAIN_THREAD
↓
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
注释:这里看着也很熟悉,好像和Schedulers.io()差不多
new Callable<Scheduler>() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
↓
↓ 是的没错最后得到的就是MainHolder.DEFAULT
↓
private static final class MainHolder {
static final Scheduler DEFAULT =
new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
}
このようにして、AndroidSchedulers.mainThread()は、最終的にHandlerSchedulerオブジェクトである新しいHandler(Looper.getMainLooper())を取得します。
HandlerSchedulerの構築パラメーターとして渡されます。
このようにして、スケジューラーを取得します。
次に、scheduler.createWorker()がどのように実装されているかを見てください
final class HandlerScheduler extends Scheduler {
注释:这个handler就是new Handler(Looper.getMainLooper())
private final Handler handler;
HandlerScheduler(Handler handler) {
this.handler = handler;
}
@Override
public Worker createWorker() {
注释1 ↓
return new HandlerWorker(handler);
}
private static final class HandlerWorker extends Worker {
private final Handler handler;
HandlerWorker(Handler handler) {
this.handler = handler;
}
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, unit.toMillis(delay));
...
return scheduled;
}
}
ワーカーを見つけることができるように、HandlerWorkerオブジェクトがcreateWorkerに返されます。
onNext→schedule()を覚えて、スケジュールでworker.schedule(Runnable)を呼び出します
ただし、この実装は親クラスのScheduler.Workerにあるため、HandlerWorkerにはschedule(Runnable run)メソッドがありません。
public abstract class Scheduler {
public abstract static class Worker implements Disposable {
@NonNull
public Disposable schedule(@NonNull Runnable run) {
注释 schedule(run, 0L, TimeUnit.NANOSECONDS)是下面的抽象方法
具体实现在其子类中,所以又回到了原来的HandlerWorker
return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
@NonNull
public abstract Disposable schedule(@NonNull Runnable run, long delay, TimeUnit unit);
}
}
上記のHandlerWorkerのソースコードを覚えていますか?
private static final class HandlerWorker extends Worker {
private final Handler handler;
HandlerWorker(Handler handler) {
this.handler = handler;
}
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
注释: 核心代码
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, unit.toMillis(delay));
...
return scheduled;
}
ハンドラーを使用してRunnableを実行用のメインスレッドに配置し、メインスレッドに切り替えられるようにします(ここではAndroidSchedulers.mainThread()を渡します)
このようにして、Runnableのrunメソッドはメインスレッドで実行されました
この時点で、Runnableのrunメソッド(つまり、ObserveOnObserver)がどのように実行されるかを確認できます。
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
...省略其它代码...
public void run() {
if (outputFused) {
不走这里 这里执行的是onNext(null)传一个null回去
drainFused();
} else {
执行这里
drainNormal();
}
}
void drainNormal() {
...
final Observer<? super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
......
终于,数据在我们observeOn的线程中传递了回去
a.onNext(v);
}
......
}
}
}
このようにして、observeOn(AndroidSchedulers.mainThread())は終了します。
注:Rxjvavaは、サブスレッドとメインスレッドを切り替えることができるため、柔軟性があります。
スレッドを柔軟に切り替えるobserveOnのコアコードは次のとおりです
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
@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));
}
}
observeOnでScheduler.newThread()を渡すと、スケジューラーはNewThreadSchedulerになり、scheduler.createWorker()はNewThreadWorkerを取得し、次にexecutor.submit(Runnable)を取得します。
observeOnでScheduler.io()を渡すと、スケジューラーはIoSchedulerになり、scheduler.createWorker()はEventLoopWorkerを取得し、次にexecutor.submit(Runnable)を取得します。
observeOnでAndroidSchedulers.mainThread()を渡すと、スケジューラーはHandlerScheduler(new Handler(Looper.getMainLooper()))になり、scheduler.createWorker()はHandlerWorkerを取得して実行します。
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, unit.toMillis(delay));
この時点で、スレッドを切り替える方法は終わりました。