Android框架源碼分析——RxJava&Schedule源碼分析

1、線程切換使用實例

Observable.create(object:ObservableOnSubscribe<String>{
    override fun subscribe(e: ObservableEmitter<String>) {
        e.onNext("A")
    }
})  .subscribeOn(Schedulers.io()) //設置訂閱線程
    .observeOn(AndroidSchedulers.mainThread()) //設置觀察者線程
    .subscribe()
  • onSubscribe():執行線程就是創建Observable的當前線程,並不訂閱線程、觀察者線程的影響,因爲從源碼中無論看出BasicFuseableObserver還是繼承類中針對onSubscribe()都沒有進行線程操作
public final void onSubscribe(Disposable s) {
        if (beforeDownstream()) {
            actual.onSubscribe(this);//調用下游的onSubscribe(),層層傳遞
            afterDownstream();
        }
}

2、observeOn():設置觀察者線程

public final Observable<T> observeOn(Scheduler scheduler) {
    return observeOn(scheduler, false, bufferSize());
}

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
    return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}

observeOn()操作符最終創建的是ObservableObserveOn對象,在ObservableObserveOn中保存設置的線程,並在執行時切換線程,在ObservableObserveOn的subscribeActual()中創建工作線程保存在Observer中,所以Observe只會作用於下游觀察者

public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
    super(source); // 保存Observable
    this.scheduler = scheduler; //保存Schedule
    this.delayError = delayError;
    this.bufferSize = bufferSize;
}
//訂閱執行的方法
@Override
protected void subscribeActual(Observer<? super T> observer) {
    if (scheduler instanceof TrampolineScheduler) { //設置爲TrampolineScheduler直接執行
        source.subscribe(observer);
    } else {
        Scheduler.Worker w = scheduler.createWorker(); // 
        source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
    }
}
2.1、 Scheduler.Worker

這裏設置的是AndroidSchedulers.mainThread(),在AndroidSchedulers中創建HandlerScheduler對象,這裏使用的是Looper.getMainLooper()工作隊列,所以觀察者執行會在主線程中執行

public final class AndroidSchedulers {
    private static final class MainHolder {
        //使用主線線程隊列創建HandlerScheduler,後面任務都會發送到MainLooper中
        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }
}
//createWorker()
@Override
public Worker createWorker() {
    return new HandlerWorker(handler); // 創建HandlerWorker
}

由上面訂閱分析知道,任務的執行會傳遞到ObserveOnObserver的onNext()中

  • ObserveOnObserver():切換線程並響應發送事件
ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
    this.actual = actual;  //下游的Observer
    this.worker = worker;  //創建的工作線程
    this.delayError = delayError;
    this.bufferSize = bufferSize;
}
@Override
public void onNext(T t) {
if (sourceMode != QueueDisposable.ASYNC) {
    queue.offer(t); //添加任務到隊列
}
    schedule();
}
void schedule() {
    if (getAndIncrement() == 0) {
        worker.schedule(this); //執行隊列任務,此處調用的是HandlerWorker
    }
}

在ObserveOnObserver的onNext()中首先將發送的事件加入隊列queue中,然後調用schedule()方法,調用worker.schedule()執行隊列任務,這理創建的是HandlerWorker對象,在HandlerWorker的schedule()中發送消息到MainLooper,最終方法執行ObserveOnObserver.run()

private static final class HandlerWorker extends Worker {
    private final Handler handler;
    HandlerWorker(Handler handler) {
        this.handler = 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, Math.max(0L, unit.toMillis(delay))); 
        return scheduled;
    }
}
  • ObserveOnObserver.run():切換線程後執行的任務
@Override
public void run() {
    if (outputFused) {
        drainFused();
    } else {
        drainNormal(); //執行主線程中的消息任務
    }
}
void drainNormal() {
    int missed = 1;
    final SimpleQueue<T> q = queue; //獲取隊列
    final Observer<? super T> a = actual; //獲取觀察者Observer
    for (;;) {
        for (;;) {
            boolean d = done;
            T v;
            try {
                v = q.poll(); //從隊列中取出數據
            } catch (Throwable ex) {
                return;
            }
            a.onNext(v); //向下遊Observer傳遞響應,此時已經找切換的線程中執行了
        }
    }
}

3、subscribeOn():設置訂閱線程

public final Observable<T> subscribeOn(Scheduler scheduler) {
 return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler)); //創建ObservableSubscribeOn實例
}
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); //封裝下游Observer
    s.onSubscribe(parent); //執行onSubscribe()
    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent))); //
}

訂閱線程操作符對應的 ObservableSubscribeOn類,ObservableSubscribeOn封裝下游觀察者,在ObservableSubscribeOn的subscribeActual中創建SubscribeTask對象,然後調用scheduler.scheduleDirect()執行SubscribeTask

  • SubscribeTask:保存觀察者,並觸發上層Observable的subscribe()執行事件發送
final class SubscribeTask implements Runnable {
    SubscribeTask(SubscribeOnObserver<T> parent) {
        this.parent = parent; // 保存Observer
    }
    @Override
    public void run() {
        source.subscribe(parent);  //在切換的線程中執行run()時觸發上層發送事件
    }
}
  • scheduler.scheduleDirect(…):切換線程
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
    final Worker w = createWorker(); //(1)
    final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
    DisposeTask task = new DisposeTask(decoratedRun, w); // 
    w.schedule(task, delay, unit); //(2)執行任務
    return task;
}

@Override
public Worker createWorker() {
    return new EventLoopWorker(pool.get()); //
}

scheduleDirect()中執行一下邏輯:

  1. 調用createWorker()創建線程Workrt,傳入緩存Worker池
  2. 創建DisposeTask保存Worker和Runnable
  3. 調用Worker執行DisposeTask
  • EventLoopWorker:執行任務
EventLoopWorker(CachedWorkerPool pool) {
    this.pool = pool;
    this.tasks = new CompositeDisposable();
    this.threadWorker = pool.get(); //獲取Worker實例,此處獲取的是NewThreadWorker實例
}

public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
    return threadWorker.scheduleActual(action, delayTime, unit, tasks); //(3)執行NewThreadWorker中方法
}
  • NewThreadWorker():真正使用線程池執行任務的地方
private final ScheduledExecutorService executor = SchedulerPoolFactory.create(threadFactory);//線程池
public Disposable scheduleDirect(final Runnable run, long delayTime, TimeUnit unit) {
    ScheduledDirectTask task = new ScheduledDirectTask(RxJavaPlugins.onSchedule(run));
    try {
        Future<?> f;
        if (delayTime <= 0L) {
            f = executor.submit(task); //(4)使用線程池執行任務
        } else {
            f = executor.schedule(task, delayTime, unit);
        }
        return task;
    } 
}
  • executor.submit(task)任務最後會最終執行SubscribeTask.run()方法,在run()中調用上層被觀察者的subscribe()方法發送事件,此時執行發送事件的線程就切換到設置的訂閱線程

4、Schedule

  • ObserverOn()和SubscribeOn()都使用到Schedule去切換工作線程,然後分別在不同的線程中執行操作,二者都是通過創建工作Worker執行事件達到線程切換的目的
public abstract class Scheduler {
public abstract Worker createWorker(); //(1)創建具體工作Worker
//(2)執行工作的方法,最終調用Worker子類中重寫的schedule()
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
    final Worker w = createWorker();
    w.schedule(task, delay, unit); 調用Worker.schedule()
    return task;
}
}
  1. 總結線程調度:首先傳入Scheduler的繼承類,調用scheduleDirect()執行任務,任務第一步調用重寫方法createWorker()創建具體實現的工作Worker,然後調用Worler.Schedule()執行具體任務,內部創建線程執行達到切換的目的;
  • IoScheduler:創建和緩存一組線程池,並使用線程池調度程序
public final class IoScheduler extends Scheduler {
}
  1. 設置方法,這裏設置RxJava內置線程
Schedulers.io()
  1. 重寫createWorker()創建具體對應的Worker對象
public Worker createWorker() {
  return new EventLoopWorker(pool.get()); //參數:CachedWorkerPool緩存池
}
  1. EventLoopWorker——IoScheduler中的Worker具體實現類,在schedule()中調用工作線程Threadworker執行任務
EventLoopWorker(CachedWorkerPool pool) {
    this.pool = pool; //保存傳入的緩存池
    this.tasks = new CompositeDisposable();
    this.threadWorker = pool.get(); //從緩存池中獲取工作線程
}
//
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
    return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
  1. ThreadWorker——真正執行任務的地方,內部初始化線程池並執行Callable,在Callable中觸發被觀察者事件的發送
 //初始化線程池
 private final ScheduledExecutorService  executor = SchedulerPoolFactory.create(threadFactory);
@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);
    try {
        if (delayTime <= 0) { //使用線程池執行任務
            f = executor.submit((Callable<Object>)sr);
        } else {
            f = executor.schedule((Callable<Object>)sr, delayTime, unit);
        }
        sr.setFuture(f);
    } 
    return sr;
}
  1. CachedWorkerPool——首先創建Worker實例,內部會使用傳入的線程工廠創建線程池,並將工作線程保存在allWorkers中,當任務完成後調用release()釋放並緩存線程
//獲取工作Worker
ThreadWorker get() {
    while (!expiringWorkerQueue.isEmpty()) { //如果緩存池不爲空,取出Worker返回
        ThreadWorker threadWorker = expiringWorkerQueue.poll();
        if (threadWorker != null) {
            return threadWorker;
        }
    }
    ThreadWorker w = new ThreadWorker(threadFactory); //
    allWorkers.add(w);
    return w;
}
void release(ThreadWorker threadWorker) { //添加緩存的ThreadWorker
    threadWorker.setExpirationTime(now() + keepAliveTime); //設置有效期
    expiringWorkerQueue.offer(threadWorker); //添加到緩存隊列
}
  • 總結線程工作流程:
  1. 在設置中傳入IOSchedule實例
  2. 切換線程時調用IOSchedule.scheduleDirect()執行任務
  3. 調用IOSchedule重寫的createWorker()創建EventLoopWorker實例
  4. EventLoopWorker中首先從IOSchedule內部緩存池中獲取ThreadWorker實例,如果沒有則創建具體實例並返回
  5. 調用Worker.schedule()方法執行任務,schedule()方法中調用ThreadWorker.scheduleActual()
  6. ThreadWorker.scheduleActual()中調用線程池執行任務
  7. 執行結束後緩存ThreadWorker實例
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章