文章目录
为什么要使用RxJava
Rx的思维,是响应式编程的思维,从起点到终点不断的链式调用,使用RxJava可以改变思维方式,提升效率。
- RxJava基于观察者设计模式,三个要素:
被观察者(起点)Observable,订阅 subscribe,观察者(终点)Observer。 - 数据从起点流向终点,中间可以做过滤,也是卡片式编程,加入各种操作符,如map、flatmap、zip、concat等。下游只找上游的类型。
例如想通过输入一个String字符串,最终转换成一个Bitmap,可以通过内部的操作符添加转换的规则,流入是一个String,流出Bitmap。
分配线程
subscribeOn 给上面代码分配线程
如:subscribeOn(Schedulers.io())
observeOn 给下面代码分配线程
如:observeOn(AndroidSchedulers.mainThread())
flatmap解决嵌套请求
给一个数据,分成多个数据
onNext(1);----->
flatmap(1–>发送3次 1 + “AAA”)----->
subscribe{“1+AAA”,“1+AAA”,“1+AAA”}
Observable
.create(new ObservableOnSubscribe<ProgramBean>() {
@Override
public void subscribe(@NonNull ObservableEmitter<ProgramBean> emitter) throws Throwable {
ProgramBean bean = getData();
emitter.onNext(bean);
}
})
.subscribeOn(Schedulers.io())
.flatMap(new Function<ProgramBean, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(ProgramBean bean) throws Throwable {
// 返回一个迭代器,会控制发射多次
return Observable.fromIterable(bean.list);
}
})
.flatMap(new Function<String, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(String s) throws Throwable {
return null;
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String o) {
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
doOnNext
当使用subscribe后,链式调用就到了终点,没有返回值可以再次进行处理了,doOnNext返回Observable,可以继续进行链式调用。常应用于 异步->UI->异步->UI->异步->UI 切换的场景。
dispose销毁
在订阅时声明到外面,在页面onDestroy时及时销毁。
设计模式
- RxJava是基于观察模式的改装
- 标准的观察者模式是有一个被观察者,多个观察者,被观察者发生改变,观察者触发改变
- RxJava是有多个被观察者,一个观察者,耦合度更低,也叫发布订阅模式
- Observer 观察者,就是一个接口,由用户来实现,传入的泛型T由onNext返回
public interface Observer<@NonNull T> {
void onSubscribe(@NonNull Disposable d);
void onNext(@NonNull T t);
void onError(@NonNull Throwable e);
void onComplete();
}
- Observable 被观察者,包含了create方法,创建一个Observalble,也定义了所有的操作符,create方法,需要用户传入一个ObservableOnSubscribe,创建一个ObservableCreate,在ObservableCreate中保存为一个成员变量,create方法会返回一个ObservableCreate对象,返回这个对象才可以继续进行链式调用,其他所有的操作符也是同理
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
}
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
...
}
- subscribe 订阅,subscribe是在ObservableSource接口中定义的方法,实现是在Observalble中,用户需要传入一个自定义的Observer,最后调用了subscribeActual(observer)方法,
@FunctionalInterface
public interface ObservableSource<@NonNull T> {
/**
* Subscribes the given {@link Observer} to this {@link ObservableSource} instance.
* @param observer the {@code Observer}, not {@code null}
* @throws NullPointerException if {@code observer} is {@code null}
*/
void subscribe(@NonNull Observer<? super T> observer);
}
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(@NonNull Observer<? super T> observer) {
Objects.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
Objects.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
//这里,最终调用了此方法
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
subscribeActual是一个抽象方法,实现是在ObservableCreate中,在ObservableCreate的subscribeActual实现中,创建一个发射器,传入observer,调用onSubscribe,这也是只要一订阅,马上就会执行subscribe回调的原因。
最后执行source.subscribe(parent); soure就是前面创建被观察者时用户传入的ObservableOnSubscribe,parent就是发射器,调用发射器的onNext,因为创建发射器时,保存了observer,这样就会调用到Observer的onNext,再回调给用户。
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
public interface Emitter<@NonNull T> {
void onNext(@NonNull T value);
void onError(@NonNull Throwable error);
void onComplete();
}
//发射器创建
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
RxJava Hook点
可以看到,Rxjava每个操作符对应都会创建一个Observablexxx,在创建这个对象之后,都会传入到RxJavaPlugins.onAssembly()中,RxJavaPlugins.onAssembly()静态方法作为了整个RxJava操作符的拦截
public static <@NonNull T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
onObservableAssembly只有setOnObservableAssembly()方法赋值
public static void setOnObservableAssembly(@Nullable Function<? super Observable, ? extends Observable> onObservableAssembly) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
RxJavaPlugins.onObservableAssembly = onObservableAssembly;
}
此方法RxJava中并未赋值,所以onAssembly中不会调用到apply()方法,只有当用户调用了setOnObservableAssembly方法时,才会调用apply(),这也是RxJava提供给用户的全局监听的方法,这里不能返回null,需要返回Observable,保证链式调用可以继续
RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
@Override
public Observable apply(Observable observable) throws Throwable {
return observable;
}
});
操作符
为了保证链式调用流程不断,RxJava采用洋葱模型,通过封包裹,拆包裹的方式,把每个操作符一层层打包,以map为例,源码如图
在调用map操作符时,传入一个Function,在调用subscribe时,会调到ObservableMap的subscribeActual方法,在方法中,包裹了一层MapObserver,又把MapObserver传入到了ObservableCreate中,再包裹一层发射器,将发射器通过参数传给用户
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
...
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
用户就可以使用发射器,调用onNext,进行拆包裹,一层一层递进地调用onNext(),最后达到“终点”,也就是用户自己实现的onNext
//用户
Observable
.create(new ObservableOnSubscribe<ProgramBean>() {
@Override
public void subscribe(@NonNull ObservableEmitter<ProgramBean> emitter) throws Throwable {
ProgramBean bean = getData();
emitter.onNext(bean);
}
})
//CreateEmitter发射器
@Override
public void onNext(T t) {
if (t == null) {
onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
//MapObserver
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
downstream.onNext(null);
return;
}
U v;
try {
v = Objects.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
downstream.onNext(v);
}
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String o) {
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
在MapObserver中调用mapper.apply(t),把变换的逻辑再交给用户,就完成了整体的流程。
线程切换原理
subscribeOn()
- 给上面的代码分配线程,常用
subscribeOn(Schedulers.io())
- 首先看Schedulers.io()是怎么做的
Schedulers.io()方法直接返回了一个IO对象,IO在静态代码块中赋值
@NonNull
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(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,还有很多不同的策略。IO实例化时,创建了一个IOTask(),IOTask()的get()方法,返回一个IoScheduler(),在IoScheduler的构造方法中,可以看到创建了线程池。也就是说,Schedulers.io()实际上就是创建了线程池
static final class IOTask implements Supplier<Scheduler> {
@Override
public Scheduler get() {
return IoHolder.DEFAULT;
}
}
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
public IoScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<>(NONE);
start();
}
@Override
public void start() {
CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
- SubscribeOn(),通过上面的分析,这里实际上是把IoScheduler作为参数传递进去了,创建Observable子类ObservableSubscribeOn来保存一份IoScheduler,同时也给父类声明的source赋值了,这个source实际上是用户上一步调用返回的Observable,在SubscribeTask的run方法中使用。在执行subscribe订阅后,会调用到subscribeActual方法
public final Observable<T> subscribeOn(@NonNull Scheduler scheduler) {
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<>(this, scheduler));
}
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> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<>(observer);
observer.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
....
}
SubscribeTask是一个Runnable,最终会把它交给线程池来运行,run方法中使用了前面保存的source,这也是可以做到给上面的代码分配线程的效果
scheduleDirect中会创建一个Worker对象,调用worker.schedule(),最终调用IoScheduler的schedule方法,最后在scheduleActual方法中,调用线程池的submit或schedule方法
@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;
}
ObserveOn()
- 给下面的代码分配线程,常用
observeOn(AndroidSchedulers.mainThread())
- AndroidSchedulers.mainThread()属于RxAndroid库中的内容,想要使用,必须导入RxAndroid库。
- 切换到主线程,使用的是Android的Handler机制。AndroidSchedulers.mainThread() 主要作用就是拿主线程的handler,保存在HandlerScheduler的成员变量中
private static final class MainHolder {
static final Scheduler DEFAULT = internalFrom(Looper.getMainLooper(), true);
}
final class HandlerScheduler extends Scheduler {
private final Handler handler;
private final boolean async;
HandlerScheduler(Handler handler, boolean async) {
this.handler = handler;
this.async = async;
}
...
}
- ObserveOn()
创建了ObservableObserveOn,传入了主线程handler的scheduler,在中也同样的,保存了一份主线程的scheduler
public final Observable<T> observeOn(@NonNull Scheduler scheduler, boolean delayError, int bufferSize) {
Objects.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<>(this, scheduler, delayError, bufferSize));
}
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;
}
...
}
在subscribeActual方法中,首先判断是不是当前执行的线程,如果不是,再切换线程
@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<>(observer, w, delayError, bufferSize));
}
}
切换线程时,首先调用主线程scheduler的createWorder方法创建worker,返回到HandlerWorker中,可以看到
@Override
public Worker createWorker() {
return new HandlerWorker(handler, async);
}
创建一个ObserveOnObserver,在调用onSubscribe或onNext等时,会调用它的schedule()方法
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
最终调用到主线程scheduler的worker的schedule方法在执行worker.schedule时,执行了,handler.sendMessage
@Override
@SuppressLint("NewApi") // Async will only be true when the API is available to call.
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 Disposable.disposed();
}
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
if (async) {
message.setAsynchronous(true);
}
handler.sendMessageDelayed(message, unit.toMillis(delay));
// Re-check disposed state for removing in case we were racing a call to dispose().
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposable.disposed();
}
return scheduled;
}
worker.schedule(this);方法中,传递的参数this为Runnable,ObserveOnObserver实现的Runnable接口,run方法也在ObserveOnObserver中可以找到,当handler切换到主线程后,执行run方法,run方法执行在主线程,最终调用了用户实现的observer.onNext等方法。
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}