内容:
- 标准观察者与RxJava观察者
- map变换操作符原理
第二节课难度曲线
标准观察者与RxJava观察者
RxJava的观察者模式是标准观察者模式改装发展而来的。
标准观察者模式
标准的观察者设计模式 —注意:在标准的观察者设计模式中,是一个“被观察者”,多个“观察者“,并且需要“被观察者”发出改变通知后,所有的”观察者”才能观察到。
RxJava的Hook点
Hook 机制简单来说就是执行某些步骤时先执行其他的某些步骤,然后再返回去继续执行原来的步骤。
RxJava 的Hook点:
//Observable.java
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
看下RxJavaPlugins.onAssembly的源码:
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
对比下RxJava 1.x和RxJava 2.x的RxJavaPlugins.onAssembly的源码:
//RxJava 1.x
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
// 提前预留 给 2.x
return source;
}
//RxJava 2.x
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
//默认情况下,f == null,因为 onObservableAssembly == null
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
如何使得onObservableAssembly不为null?调用RxJavaPlugins.setOnObservableAssembly设置RxJavaPlugins.onObservableAssembly的值即可:
/**
* Sets the specific hook function.
* @param onObservableAssembly the hook function to set, null allowed
*/
@SuppressWarnings("rawtypes")
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;
}
测试例子:
/**
* TODO RxJava Hook 点
*/
public class SourceActivity1 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//
// 我想用了多少给 Map操作 flatMap
// Hook之前的监听
RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
@Override
public Observable apply(Observable observable) throws Exception {
Log.d(Flag.TAG, "apply: 整个项目 全局 监听 到底有多少地方使用 RxJava:" + observable);
// 伪代码
/*if (observable === ObservableMap)
return null;*/
return null; // 不破坏人家的功能
}
});
testHook();
}
RxJava的观察者模式
RxJava的观察者模式与标准观察者模式完全不一样。
先 简单的分析 这3步的 源码,打通主线流程 【TODO RxJava的观察者模式】
Observable创建过程的重要的点记录:
Observable.create时,就是把我们传递的自定义ObservableOnSubscribe对象,包装成ObservableCreate对象,然后再返回ObservableCreate对象, 注意:在ObservableCreate中存了一份source
Observable创建过程时序图如下:
这个是非常详细的时序图,也就是刚刚我们分析源码时的各个细节。
Observable.create()返回的是ObservableCreate对象。
Observable 与 Observer 订阅的过程 重要的点记录:
ObservableCreate.subscribe
ObservableCreate. subscribeActual方法中,会 new CreateEmitter(注意:此observer就是 我们自己定义的Observer) 发射器
Observable 与 Observer 订阅的过程 重要步骤:
这个图是简化版。
Observable 与 Observer 订阅的过程 重要步骤(废弃):
Observable 与 Observer 订阅的过程时序图如下:
Observable 与 Observer 订阅过程总结
RxJava简单订阅过程:
从直观角度分析 标准观察者模式 与 RxJava观察者模式
两者对比:标准的观察者设计模式与RxJava观察者设计模式
在标准的观察者设计模式中,是一个“被观察者”,多个“观察者“,并且需要“被观察者”发出改变通知后,所有的”观察者”才能观察到。
在RxJava观察者设计模式中,是多个“被观察者”,一个“观察者”,并且需要 起点 和 终点 在 “订阅” 一次后,才发出改变通知,终点(观察者)才能观察到。
可以看下Observable的源码:
//Observable.java
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
可以看到create和map返回的都是Observable对象,中间可以调用很多次map,因此创建了很多个“被观察者”,而只new Observer了一次,即只创建一个“观察者”。
从模式角度分析 标准观察者模式 与 RxJava观察者模式
两者对比:
在标准的观察者设计模式中:当发出通知改变时,会遍历Observable里面的容器,此容器里面有10个Observer,就会通知10个Observer。
在RxJava观察者设计模式中:分发事件时,会拿到发射器,通过发射器关联 到 我们自定义的Observer,发射器调用 到 我们自定义的Observer。
观察者设计模式与发布订阅模式:
Map变换操作符原理
map操作符实际做的事情就是类型的转变。
map示意图:一个Map源码分析
加入map操作符后的流程:
从右往左的过程就是Observer外面不断加一层Observable的过程,到最顶层的时候,ObservableOnSubscribe的subscribe()会调用ObservableEmitter的onNext()开始从左往右执行,这个过程是不断执行外面一层Observable的Observer的onNext()的过程,最终执行最底层的Observer的onNext()。
封包拆包:
最里面的是Observer,然后外面一层一层加Observable,到最顶层时,ObservableOnSubscribe的subscribe()方法会执行ObservableEmitter的onNext(),然后往下不断调用Observable的Observer的onNext()直到最底层的Observer的onNext()。
每个Observable里面都有Observer,比如看下ObservableMap:
//ObservableMap.java
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) {
//subscribeActual的过程就是用MapObserver包装了操作(function)的过程
source.subscribe(new MapObserver<T, U>(t, function));
}
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
final Function<? super T, ? extends U> mapper;
...
}
终极三部曲:
RxJava装饰模型
装饰模型:
作业
画出map变换操作符详细图