转载请注明出处,谢谢https://blog.csdn.net/HarryWeasley/article/details/105363078
下方是一个最简单切换线程的方式,本篇文章以下方的代码引入。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onComplete();
}
})
//切换到子线程
.subscribeOn(Schedulers.io())
//切换主线程
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
Log.d(TAG, "this is result"+value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
如上的代码,当我们调用了observeOn(AndroidSchedulers.mainThread())这句话,就切换了到主线程,现在跟着源码看看,rxJava是如何操作的。
Observable类:
public final Observable<T> observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
//检查schedule是否为null
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
//检查bufferSize是否大于0,默认是128
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
进入到RxJavaPlugins.onAssembly这个方法中
RxJavaPlugins类:
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
//这里是个hook机制,onObservableAssembly默认是null
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
//f为null,直接返回source,这里是ObservableObserveOn
return source;
}
注释已经写明了,所以我们直接看传入的ObservableObserveOn
ObservableObserveOn类:
//本例是 AndroidSchedulers.mainThread()
final Scheduler scheduler;
...
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) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
//生成了一个worker,这里是重点1
Scheduler.Worker w = scheduler.createWorker();
//用ObserveOnObserver订阅上游数据源。这样当数据从上游push下来,会由ObserveOnObserver对应的onXXX()处理
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
这里有个重点需要注意一些scheduler.createWorker(),返回了一个worker,之后会进行解释。
现在,我们看下ObserveOnObserver类的部分方法,还是那句话,本篇文章,主要是查看如何切换到主线程的
ObserveOnObserver类:
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
...
@Override
public void onNext(T t) {
// 执行过error / complete 会是true
if (done) {
return;
}
// 如果数据源类型不是异步的, 默认不是
if (sourceMode != QueueDisposable.ASYNC) {
// 将上游push过来的数据 加入 queue里
queue.offer(t);
}
//开始进入对应Workder线程,在线程里 将queue里的t 取出 发送给下游Observer
schedule();
}
...
void schedule() {
if (getAndIncrement() == 0) {
//将ObserveOnObserver(实现了Runnable)加入worker,这里是重点2
worker.schedule(this);
}
}
...
}
在schedule调用了worker.schedule(this)方法,我们可以思考,在这边将Runnable加入了worker中,那么一定会调用其实现的run方法,而run方法里就是主线程了。
我们去看内部调用方法:
Scheduler类:
public Disposable schedule(@NonNull Runnable run) {
return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
//抽象方法,所以我们要找到实现它的类
public abstract Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit);
这里的schedule是AndroidSchedulers.mainThread(),那么我们去这个类去看看,
//AndroidSchedulers类:
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
//RxAndroidPlugins类
public static Scheduler onMainThreadScheduler(Scheduler scheduler) {
if (scheduler == null) {
throw new NullPointerException("scheduler == null");
}
//其实这里还是一个hook机制,默认这边的onMainThreadHandler为null
Function<Scheduler, Scheduler> f = onMainThreadHandler;
if (f == null) {
//直接返回传入的scheduler
return scheduler;
}
return apply(f, scheduler);
}
通过上方的代码分析,那么直接看MAIN_THREAD是如何生成的,继续看代码:
//AndroidSchedulers类
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
new Callable<Scheduler>() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
//RxAndroidPlugins类:
public static Scheduler initMainThreadScheduler(Callable<Scheduler> scheduler) {
if (scheduler == null) {
throw new NullPointerException("scheduler == null");
}
//又是一个hook机制,onInitMainThreadHandler默认为null
Function<Callable<Scheduler>, Scheduler> f = onInitMainThreadHandler;
if (f == null) {
//返回这个方法
return callRequireNonNull(scheduler);
}
return applyRequireNonNull(f, scheduler);
}
//RxAndroidPlugins类:
static Scheduler callRequireNonNull(Callable<Scheduler> s) {
try {
//这边调用了call方法,拿到scheduler,并且返回
Scheduler scheduler = s.call();
if (scheduler == null) {
throw new NullPointerException("Scheduler Callable returned null");
}
return scheduler;
} catch (Throwable ex) {
throw Exceptions.propagate(ex);
}
}
通过 Scheduler scheduler = s.call();这个方法得知,最上面的call代码返回的值,就是这个scheduler,就是这个MainHolder.DEFAULT。
AndroidSchedulers类:
private static final class MainHolder {
//最终的scheduler方法
static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
可以看出来,这里传入了一个主线程的Handler
我们去看看HandlerScheduler类方法
HandlerScheduler类:
final class HandlerScheduler extends Scheduler {
//主线程的handler
private final Handler handler;
HandlerScheduler(Handler handler) {
this.handler = handler;
}
...
@Override
public Worker createWorker() {
//这里不就是重点1,调用的方法吗,所以worker就是HandlerWorker
return new HandlerWorker(handler);
}
}
从上面的代码,我们终于找到了worker的实现类了,我们找到了worker类,那么我们就去找重点2的那个方法,看实现的schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit)的具体实现代码。
去看HandlerWorker的实现方法
//HandlerWorker类
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
hook机制,其实就是获取到run
run = RxJavaPlugins.onSchedule(run);
//一个代理类,其实还是一个实现的Runnable的类
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
//获取到message,将scheduled赋值到callBack里
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
//handler发送消息,delay是0
handler.sendMessageDelayed(message, unit.toMillis(delay));
...
return scheduled;
}
//Message类
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
//给message的callback赋值上面的Runnable
m.callback = callback;
return m;
}
上面的代码,获取到一个message,然后直接通过handler发送消息,这个handler之前已经说过,是一个主线程Looper.getMainLooper()的handler。其实之后,就是handler机制了的,最终主线程的Looper循环,获取到message信息,最终会调用handler的dispatchMessage方法。
public void dispatchMessage(@NonNull Message msg) {
//这里已经是主线程了
if (msg.callback != null) {
//之前将其callback赋值了,所以会执行此地方的代码
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//这里不就是我们正常情况下,自定义handler处理代码的地方吗
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
//从这里可以看到,调用了callback的run方法
message.callback.run();
}
这里可以自己敲代码验证一下,例子如下:
case R.id.btn10:
//button点击后,发送一个消息
Handler handler = new Handler(Looper.getMainLooper());
myRunnable runnable = new myRunnable();
Message message = Message.obtain(handler, runnable);
handler.sendMessage(message);
break;
...
class myRunnable implements java.lang.Runnable {
@Override
public void run() {
Log.d(TAG, "这里执行了" + Thread.currentThread());
}
}
执行结果为:这里执行了Thread[main,5,main]
从上面的代码知道,就是传入的message的callback执行了run方法,callback就是代理类ScheduledRunnable,那我们看下他的run方法
private static final class ScheduledRunnable implements Runnable, Disposable {
@Override
public void run() {
try {
//这里已经是主线程了
//这里的delegate就是重点2传入的Runnable,也就是ObserveOnObserver
delegate.run();
} catch (Throwable t) {
RxJavaPlugins.onError(t);
}
}
}
从上面的代码中,可知,通过消息机制,已经进入了主线程,这个时候,再调用ObserveOnObserver的run方法,我们继续看代码
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
...
@Override
public void run() {
//从这里开始,这个方法已经是在Workder对应的线程里执行的了
//默认是false
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
...
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;
for (;;) {
// 如果已经 终止 或者queue空,则跳出函数,
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
//从queue里取出一个值
v = q.poll();
} catch (Throwable ex) {
//异常处理 并跳出函数
Exceptions.throwIfFatal(ex);
s.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
...
//发送给下游了
a.onNext(v);
}
...
}
}
}
从上面,就看出来了,在下游的onNext方法里,已经变成了主线程了。
总结:
这样整个切换到主线程的流程已经分析完了。本篇文章结束。
参考文章:https://www.jianshu.com/p/6ef45f8ee79d