Android知识总结
一、调度器 Scheduler
如果你想给Observable操作符链添加多线程功能,你可以指定操作符(或者特定的Observable)在特定的调度器(Scheduler)上执行。
使用ObserveOn和SubscribeOn操作符,你可以让Observable在一个特定的调度器上执行,ObserveOn指示一个Observable在一个特定的调度器上调用观察者的onNext, onError和onCompleted方法,SubscribeOn更进一步,它指示Observable将全部的处理过程(包括发射数据和通知)放在特定的调度器上执行。
Scheduler为调度器,也可以叫做线程控制器。RxJava通过它来指定每一段代码在那个线程中运行。在不指定线程的情况下,RxJava遵循线程不变的原则,即:在那个线程调用subscribe(),就在那个线程生产事件;在那个线程生产事件,就在那个线程消耗事件。如果需要切换线程,就需要使用Scheduler来进行控制。
Flowable 很多操作符内部都使用了背压策略, 从而避免过多的数据填满内部的队列. (Flowable 的默认队列是 128)。
1.1、 调度器的种类
下表展示了RxJava中可用的调度器种类:
Schedulers.computation( )
: 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io()),否则 I/O 操作的等待时间会浪费 CPU;默认线程数等于处理器的数量 。Schedulers.from(executor)
使用指定的Executor作为调度器。Schedulers.immediate( )
在当前线程立即开始执行任务,相当于不指定线程。这是默认的 Scheduler。Schedulers.io( )
:用于IO密集型任务, 如:(读写文件、读写数据库、网络信息交互等)。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,大量的I/O调度操作将创建许多个线程并占用内存,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器 。Schedulers.newThread( )
:为每个任务创建一个新线程,并在新线程执行操作。Schedulers.trampoline( )
:当其它排队的任务完成后,在当前线程排队开始执行。AndroidSchedulers.mainThread()
:它指定的操作将在 Android 主线程运行。主要用于Android的UI更新操作。
1.2、SubscribeOn
Observable
.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter emitter) throws Exception {
//io 线程
emitter.onNext(11);
emitter.onComplete();
}
})
//步骤二
.subscribeOn(
//步骤一
Schedulers.io())
.subscribe(new Observer() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//调用者的线程
}
@Override
public void onNext(@NonNull Integer integer) {
//io 线程
}
@Override
public void onError(@NonNull Throwable e) { }
@Override
public void onComplete() { }
});
}
根据上面代码和试图可以看到SubscribeOn
主要用于上游事件线程的切换。
下面我们根据源码进行分析:
1.2.1、步骤一分析
@onNull
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
在Schedulers
类中我们可以看到调度器定义的IO操作。
@NonNull
static final Scheduler SINGLE;
//用于计算任务
@NonNull
static final Scheduler COMPUTATION;
//用于IO密集型任务
@NonNull
static final Scheduler IO;
//当其它排队的任务完成后,在当前线程排队开始执行
@NonNull
static final Scheduler TRAMPOLINE;
//为每个任务创建一个新线程
@NonNull
static final Scheduler NEW_THREAD;
static final class SingleHolder {
static final Scheduler DEFAULT = new SingleScheduler();
}
static final class ComputationHolder {
static final Scheduler DEFAULT = new ComputationScheduler();
}
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
static final class NewThreadHolder {
static final Scheduler DEFAULT = new NewThreadScheduler();
}
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()
方法执行
@NonNull
public static Scheduler initIoScheduler(@NonNull Callable defaultScheduler) {
ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null");
//运用 HOOK 可以统计 IO 创建次数
Function super Callable, ? extends Scheduler> f = onInitIoHandler;
if (f == null) {
return callRequireNonNull(defaultScheduler);
}
return applyRequireNonNull(f, defaultScheduler);
}
HOOK的使用
RxJavaPlugins.setInitIoSchedulerHandler(new Function, Scheduler>() {
@Override
public Scheduler apply(Callable schedulerCallable) throws Exception {
Log.d(TAG, "apply: 全局 监听 init scheduler:" +schedulerCallable.call());
return schedulerCallable.call();
}
});
new IOTask()
的创建
static final class SingleHolder {
static final Scheduler DEFAULT = new SingleScheduler();
}
static final class ComputationHolder {
static final Scheduler DEFAULT = new ComputationScheduler();
}
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
static final class NewThreadHolder {
static final Scheduler DEFAULT = new NewThreadScheduler();
}
static final class IOTask implements Callable {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
}
static final class NewThreadTask implements Callable {
@Override
public Scheduler call() throws Exception {
return NewThreadHolder.DEFAULT;
}
}
static final class SingleTask implements Callable {
@Override
public Scheduler call() throws Exception {
return SingleHolder.DEFAULT;
}
}
static final class ComputationTask implements Callable {
@Override
public Scheduler call() throws Exception {
return ComputationHolder.DEFAULT;
}
}
我们再看new IoScheduler()
里面做些什么
// 线程池的 factory,给每个新建的线程设置一个具有识别度的线程名
static final RxThreadFactory WORKER_THREAD_FACTORY;
//线程池
static final CachedWorkerPool NONE;
static {
SHUTDOWN_THREAD_WORKER = new ThreadWorker(new RxThreadFactory("RxCachedThreadSchedulerShutdown"));
SHUTDOWN_THREAD_WORKER.dispose();
int priority = Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY,
Integer.getInteger(KEY_IO_PRIORITY, Thread.NORM_PRIORITY)));
WORKER_THREAD_FACTORY = new RxThreadFactory(WORKER_THREAD_NAME_PREFIX, priority);
EVICTOR_THREAD_FACTORY = new RxThreadFactory(EVICTOR_THREAD_NAME_PREFIX, priority);
//创建线程池
NONE = new CachedWorkerPool(0, null, WORKER_THREAD_FACTORY);
NONE.shutdown();
}
public IoScheduler() {
this(WORKER_THREAD_FACTORY);
}
CachedWorkerPool
是IoScheduler
的内部类
static final class CachedWorkerPool implements Runnable {
private final long keepAliveTime;
private final ConcurrentLinkedQueue expiringWorkerQueue;
final CompositeDisposable allWorkers;
private final ScheduledExecutorService evictorService;
private final Future> evictorTask;
private final ThreadFactory threadFactory;
CachedWorkerPool(long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
this.expiringWorkerQueue = new ConcurrentLinkedQueue();
this.allWorkers = new CompositeDisposable();
this.threadFactory = threadFactory;
ScheduledExecutorService evictor = null;
Future> task = null;
if (unit != null) {
//创建一个定时线程池,一个任务一个任务执行的场景
evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY);
task = evictor.scheduleWithFixedDelay(this, this.keepAliveTime, this.keepAliveTime, TimeUnit.NANOSECONDS);
}
evictorService = evictor;
evictorTask = task;
}
@Override
public void run() {
evictExpiredWorkers();
}
ThreadWorker get() {
if (allWorkers.isDisposed()) {
return SHUTDOWN_THREAD_WORKER;
}
while (!expiringWorkerQueue.isEmpty()) {
ThreadWorker threadWorker = expiringWorkerQueue.poll();
if (threadWorker != null) {
return threadWorker;
}
}
// No cached worker found, so create a new one.
ThreadWorker w = new ThreadWorker(threadFactory);
allWorkers.add(w);
return w;
}
void release(ThreadWorker threadWorker) {
// Refresh expire time before putting worker back in pool
threadWorker.setExpirationTime(now() + keepAliveTime);
expiringWorkerQueue.offer(threadWorker);
}
void evictExpiredWorkers() {
if (!expiringWorkerQueue.isEmpty()) {
long currentTimestamp = now();
for (ThreadWorker threadWorker : expiringWorkerQueue) {
if (threadWorker.getExpirationTime() <= currentTimestamp) {
if (expiringWorkerQueue.remove(threadWorker)) {
allWorkers.remove(threadWorker);
}
} else {
// Queue is ordered with the worker that will expire first in the beginning, so when we
// find a non-expired worker we can stop evicting.
break;
}
}
}
}
long now() {
return System.nanoTime();
}
void shutdown() {
allWorkers.dispose();
if (evictorTask != null) {
evictorTask.cancel(true);
}
if (evictorService != null) {
evictorService.shutdownNow();
}
}
}
当创建io
线程后,会把线程放到线程池中执行。
然后回到上面io()
方法,看RxJavaPlugins#onIoScheduler
方法的执行
@NonNull
public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
//运用 Hook 技术,可以统计IO 线程的使用次数。
Function super Scheduler, ? extends Scheduler> f = onIoHandler;
if (f == null) {
return defaultScheduler;
}
return apply(f, defaultScheduler);
}
-
Hook
的使用放视
RxJavaPlugins.setIoSchedulerHandler(new Function() {
@Override
public Scheduler apply(Scheduler scheduler) throws Exception {
Log.d(TAG, "apply: 全局 监听 scheduler:" +scheduler);
return scheduler;
}
});
1.2.2、步骤二分析
执行subscribeOn
方法,会创建一个ObservableSubscribeOn
对象:
public final Observable subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
}
ObservableSubscribeOn
相关代码
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer super T> s) {
// s 指下游的 observer
//创建包囊 SubscribeOnObserver,把 Observer 打包
final SubscribeOnObserver parent = new SubscribeOnObserver(s);
//订阅
s.onSubscribe(parent);
//步骤三
parent.setDisposable(
//步骤二
scheduler.scheduleDirect(
//步骤一
new SubscribeTask(parent)));
}
static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer super T> actual;
final AtomicReference s;
SubscribeOnObserver(Observer super T> actual) {
this.actual = actual;
this.s = new AtomicReference();
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this.s, s);
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
actual.onError(t);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void dispose() {
DisposableHelper.dispose(s);
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
void setDisposable(Disposable d) {
DisposableHelper.setOnce(this, d);
}
}
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
//source 指的是上游的 Obserable
source.subscribe(parent);
}
}
}
- 步骤一
SubscribeTask
是iObservableSubscribeOn
的内部类
final class SubscribeTask implements Runnable {
//用 SubscribeOnObserver 打包的 Observer
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
//source 指的是上游的 Obserable
source.subscribe(parent);
}
}
- 步骤二
执行Scheduler#scheduleDirect
方法
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
//等于执行 IoScheduler.createWorker(){new EventLoopWorker(pool.get());}
final Worker w = createWorker(); //(1)
//把 SubscribeTask 包装 Runnable, run 指的是 SubscribeTask
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); //(2)
//又包装一层,放入线程池
DisposeTask task = new DisposeTask(decoratedRun, w); //(3)
//执行线程池任务
w.schedule(task, delay, unit); //(4)
return task;
}
- (1)
createWorker()
实际执行的是IoScheduler#createWorker
方法:
@Override
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
public int size() {
return pool.get().allWorkers.size();
}
static final class EventLoopWorker extends Scheduler.Worker {
private final CompositeDisposable tasks;
private final CachedWorkerPool pool;
private final ThreadWorker threadWorker;
final AtomicBoolean once = new AtomicBoolean();
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get();
}
@Override
public void dispose() {
if (once.compareAndSet(false, true)) {
tasks.dispose();
// releasing the pool should be the last action
pool.release(threadWorker);
}
}
@Override
public boolean isDisposed() {
return once.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;
}
//调度线程池任务
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
}
- (2)调用
RxJavaPlugins#onSchedule
对SubscribeTask
进行包装
public static Runnable onSchedule(@NonNull Runnable run) {
ObjectHelper.requireNonNull(run, "run is null");
// HOOK 节点
Function super Runnable, ? extends Runnable> f = onScheduleHandler;
if (f == null) {
return run;
}
//把 SubscribeTask 包装 成 Runnable 返回
return apply(f, run);
}
- (3)
Scheduler#DisposeTask
对Runnable再次封装成DisposeTask
。
static final class DisposeTask implements Disposable, Runnable, SchedulerRunnableIntrospection {
final Runnable decoratedRun;
final Worker w;
Thread runner;
DisposeTask(Runnable decoratedRun, Worker w) {
this.decoratedRun = decoratedRun;
//w 指的是 : 在线程池返回的 IO 任务
this.w = w;
}
@Override
public void run() {
runner = Thread.currentThread();
try {
decoratedRun.run();
} finally {
dispose();
runner = null;
}
}
@Override
public void dispose() {
if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
((NewThreadWorker)w).shutdown();
} else {
w.dispose();
}
}
@Override
public boolean isDisposed() {
return w.isDisposed();
}
@Override
public Runnable getWrappedRunnable() {
return this.decoratedRun;
}
}
- (4)执行调度
Scheduler
里的抽象方法
public abstract Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit);
IoScheduler#EventLoopWorker#schedule
执行线程池调度
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);
}
调用NewThreadWorker#scheduleActual
执行线程池任务
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
然后回调到Scheduler
的内部类DisposeTask
,执行里面的 run
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;
}
@Override
public void run() {
runner = Thread.currentThread();
try {
decoratedRun.run();
} finally {
dispose();
runner = null;
}
}
@Override
public void dispose() {
if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
((NewThreadWorker)w).shutdown();
} else {
w.dispose();
}
}
@Override
public boolean isDisposed() {
return w.isDisposed();
}
}
最后回调到ObservableSubscribeOn
的内部类SubscribeTask
,执行里面的 run
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
//上游传的 Obserable
source.subscribe(parent);
}
}
- 步骤三
void setDisposable(Disposable d) {
DisposableHelper.setOnce(this, d);
}
public static boolean setOnce(AtomicReference field, Disposable d) {
ObjectHelper.requireNonNull(d, "d is null");
// cas 操作
if (!field.compareAndSet(null, d)) {
d.dispose();
if (field.get() != DISPOSED) {
reportDisposableSet();
}
return false;
}
return true;
}
1.2.3、总结
SubscribeOn
整体流程图如下:
1.3、ObserveOn
ObserveOn
主要用于下游事件切换线程:执行图如下
- 代码分析
Observable
.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter emitter) throws Exception {
//io 线程
emitter.onNext(11);
emitter.onComplete();
}
})
.subscribeOn(Schedulers.io())
//步骤二
.subscribeOn(
//步骤一
AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//调用者的线程
}
@Override
public void onNext(@NonNull Integer integer) {
//主线程
}
@Override
public void onError(@NonNull Throwable e) { }
@Override
public void onComplete() { }
});
1.3.1、步骤一
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
调用RxAndroidPlugins#onMainThreadScheduler
里面可以进行HOOK。
public static Scheduler onMainThreadScheduler(Scheduler scheduler) {
if (scheduler == null) {
throw new NullPointerException("scheduler == null");
}
//HOOK
Function f = onMainThreadHandler;
if (f == null) {
return scheduler;
}
return apply(f, scheduler);
}
接下来我们看MAIN_THREAD
的创建过程
public final class AndroidSchedulers {
private static final class MainHolder {
//运用静态内部类的单例模式
//里面用 Looper.getMainLooper() 创建 Handler ,利用 Handler 进行线程切换
static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
//HOOK
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
new Callable() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
//切换主线程
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
//自己定义切换的线程类型
public static Scheduler from(Looper looper) {
if (looper == null) throw new NullPointerException("looper == null");
return new HandlerScheduler(new Handler(looper));
}
private AndroidSchedulers() {
throw new AssertionError("No instances.");
}
}
再看HandlerScheduler
里面的代码,怎么处理创建的 Handler
final class HandlerScheduler extends Scheduler {
//用来进行线程切换,并加入队列中发送
private final Handler handler;
HandlerScheduler(Handler handler) {
//存上面传过来的 Handler
this.handler = handler;
}
@Override
public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
if (run == null) throw new NullPointerException("run == null");
if (unit == null) throw new NullPointerException("unit == null");
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
handler.postDelayed(scheduled, Math.max(0L, unit.toMillis(delay)));
return scheduled;
}
@Override
public Worker createWorker() {
return new HandlerWorker(handler);
}
private static final class HandlerWorker extends Worker {
private final Handler handler;
private volatile boolean disposed;
HandlerWorker(Handler handler) {
this.handler = handler;
}
// run 指的是 ObservableObserveOn 的 run任务
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();
}
//HOOK
run = RxJavaPlugins.onSchedule(run);
//把任务 run 打包到 ScheduledRunnable 任务中
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
//把 ScheduledRunnable 打包到 Message 中
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
//利用Handler发送消息
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
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;
}
}
private static final class ScheduledRunnable implements Runnable, Disposable {
private final Handler handler;
private final Runnable delegate;
private volatile boolean disposed;
ScheduledRunnable(Handler handler, Runnable delegate) {
this.handler = handler;
this.delegate = delegate;
}
@Override
public void run() {
try {
delegate.run();
} catch (Throwable t) {
IllegalStateException ie =
new IllegalStateException("Fatal Exception thrown on Scheduler.", t);
RxJavaPlugins.onError(ie);
Thread thread = Thread.currentThread();
thread.getUncaughtExceptionHandler().uncaughtException(thread, ie);
}
}
@Override
public void dispose() {
disposed = true;
handler.removeCallbacks(this);
}
@Override
public boolean isDisposed() {
return disposed;
}
}
}
1.3.2、步骤二
observeOn
执行过程
public final Observable observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
// scheduler 为用 AndroidSchedulers.mainThread() 创建的 HandlerScheduler
return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
}
创建ObservableObserveOn
对象
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
// scheduler 为用 AndroidSchedulers.mainThread() 创建的 HandlerScheduler
final Scheduler scheduler;
final boolean delayError;
final int bufferSize;
public ObservableObserveOn(ObservableSource source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source);
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
//订阅 , observer 为下游的订阅的观察者
@Override
protected void subscribeActual(Observer super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
// TrampolineScheduler调度器表示在当前事件流的线程执行任务
source.subscribe(observer);
} else {
//切换线程时执行
//调用 HandlerScheduler 的 createWorker 创建 HandlerWorker 调度器
Scheduler.Worker w = scheduler.createWorker();
//用ObserveOnObserver 给 observer 打包
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
private static final long serialVersionUID = 6576896619930983584L;
//目标观察者
final Observer super T> actual;
//调度器(HandlerScheduler)工作线程池
final Scheduler.Worker worker;
final boolean delayError;
final int bufferSize;
//数据缓冲队列
SimpleQueue queue;
Disposable s;
Throwable error;
volatile boolean done;
volatile boolean cancelled;
int sourceMode;
boolean outputFused;
ObserveOnObserver(Observer super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
this.actual = actual;
this.worker = worker;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
if (s instanceof QueueDisposable) {
@SuppressWarnings("unchecked")
QueueDisposable qd = (QueueDisposable) s;
int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
if (m == QueueDisposable.SYNC) {
sourceMode = m;
queue = qd;
done = true;
//调度
actual.onSubscribe(this);
schedule();
return;
}
if (m == QueueDisposable.ASYNC) {
sourceMode = m;
queue = qd;
//调度
actual.onSubscribe(this);
return;
}
}
queue = new SpscLinkedArrayQueue(bufferSize);
actual.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t); //数据缓存入队列
}
schedule();
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
error = t;
done = true;
schedule();
}
@Override
public void onComplete() {
if (done) {
return;
}
done = true;
schedule();
}
@Override
public void dispose() {
if (!cancelled) {
cancelled = true;
s.dispose();
worker.dispose();
if (getAndIncrement() == 0) {
queue.clear();
}
}
}
@Override
public boolean isDisposed() {
return cancelled;
}
void schedule() {
if (getAndIncrement() == 0) {
//执行 HandlerWorker 里面的 schedule方法
//然后回调当前Run()方法
// (1)
worker.schedule(this);
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue q = queue;
final Observer super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
//数据接收
a.onNext(v);
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
void drainFused() {
int missed = 1;
for (;;) {
if (cancelled) {
return;
}
boolean d = done;
Throwable ex = error;
if (!delayError && d && ex != null) {
actual.onError(error);
worker.dispose();
return;
}
actual.onNext(null);
if (d) {
ex = error;
if (ex != null) {
actual.onError(ex);
} else {
actual.onComplete();
}
worker.dispose();
return;
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
@Override
public void run() {
//是否需要丢弃
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
boolean checkTerminated(boolean d, boolean empty, Observer super T> a) {
if (cancelled) {
queue.clear();
return true;
}
if (d) {
Throwable e = error;
if (delayError) {
if (empty) {
if (e != null) {
a.onError(e);
} else {
a.onComplete();
}
worker.dispose();
return true;
}
} else {
if (e != null) {
queue.clear();
a.onError(e);
worker.dispose();
return true;
} else
if (empty) {
a.onComplete();
worker.dispose();
return true;
}
}
}
return false;
}
@Override
public int requestFusion(int mode) {
if ((mode & ASYNC) != 0) {
outputFused = true;
return ASYNC;
}
return NONE;
}
@Nullable
@Override
public T poll() throws Exception {
return queue.poll();
}
@Override
public void clear() {
queue.clear();
}
@Override
public boolean isEmpty() {
return queue.isEmpty();
}
}
}
我们看(1)的调用过程:
执行Scheduler#schedule
方法
public Disposable schedule(@NonNull Runnable run) {
return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
会调到HandlerScheduler
的静态内部类HandlerWorker
,里面schedule
方法
// run 指的是 ObservableObserveOn 的 run任务
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();
}
//HOOK
run = RxJavaPlugins.onSchedule(run);
//把任务 run 包装到 ScheduledRunnable 任务中
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
//把 ScheduledRunnable 打包到 Message 中
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
//利用Handler发送消息
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposables.disposed();
}
return scheduled;
}
1.4、总结
上面的代码终结为下图:
二、背压
Back Pressure
经常被翻译为 背压. 是指在异步场景下,被观察者
发送事件速度远快于观察者
处理的速度, 从而导致下游的buffer
溢出, 这种现象叫做背压。
由于观察者与被观察者处于不同线程,所以RxJava内部使用队列来存储事件,Android中默认队列缓存buffersize为16
,所以当事件累计超过16个时就会抛出MissingBackpressureException
的异常。解决这种问题就需要对被观察者进行流速控制了,而背压正是应对这种问题的一种策略
对于Cold Observable可以采用pull
方式来处理背压,但是Hot Observable不适合用pull模型来处理,因为数据会无限的产生,最好采用一些控制策略,比如已经提供的:Buffer
,Window
,Sample
,Debounce
操作符。
另外Flowable类是专门用于背压处理的,其它的几个Observable是不支持背压的,但是提供了一些策略可以临时存储一些数据,缓解生产数据量过多问题。
-
onBackpressureDrop
:如果消费者无法处理数据,则 onBackpressureDrop 就将observable发送的事件抛弃掉,直到subscriber再次调用request(n)方法的时候,就发送给它这之后的n个事件。
Observable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressureDrop()
.observeOn(Schedulers.newThread())
.subscribe(
i -> {
System.out.println(i);
try {
Thread.sleep(100);
} catch (Exception e) { }
},
System.out::println);
结果:
0
1
2
...
126
127
12861
12862
...
-
onBackpressurebuffer
:nBackpressureBuffer 会缓存所有当前无法消费的数据,直到 Observer 可以处理为止。
Observable.interval(1, TimeUnit.MILLISECONDS)
.onBackpressureBuffer(1000)
.observeOn(Schedulers.newThread())
.subscribe(
i -> {
System.out.println(i);
try {
Thread.sleep(100);
} catch (Exception e) { }
},
System.out::println
);
Flowable类
1 使用Observable转换为Flowable,指定背压策略。
Observable.range(1,100)
.toFlowable(BackpressureStrategy.DROP)
BackpressureStrategy
MISSING:没有任何背压处理策略,如果生产数据过快,可能产生MissingBackpressureException异常,最好
Error
:在数据生产过快时,抛出MissingBackpressureException异常Latest
:当数据生产过快,保留最新生产的数据DROP
:当生产数据过快时,最新生产的数据进行丢弃Buffer
:buffer所有下游要消费的数据,直到被消费
三、操作符
RxJava提供了几个操作符,在一定程度上也能满足我们的需求。
buffer()
:先将生产的数据放到buffer中,可以指定buffer的大小,这样可以给消费者缓解一些时间来处理生产过快的数据。不过如果数据过多的话,还是会导致资源问题window()
:告诉Observable把数据进行打包,一次发一批数据给消费者,而不是一个个的发送。消费者采用一些方式可以快速处理一批数据,相比一个个处理不容易出现生产者生产过多的现象。sample()
:在一段时间内,只发送这段时间里最后一个数据给下游进行处理,throttleFirst()和sample基本相同,在一段时间内,只发送这段时间的第一个数据给下游debouce()
:在一段时间中,没有新数据产生的话,发送最后产生的那个数据。