一.标准观察者
1.标准的观察者设计模式
一个被观察者,多个观察者
绿色区域是被观察者
红色区域是观察者
被观察者的抽象(抽象类或者接口)…
蓝色区域 把观察者丢给被观察者
被观察者会有容器,把被观察者丢到容器里面
代码实现
// TODO 抽象层 被观察者
public interface Observable {
// 关注
void addObserver(Observer observer);
// 取消关注
void removeObserver(Observer observer);
// 被观察者发出了改变
void notifyObservers();
// 编辑 发布一条消息
void pushMessage(String message);
}
// TODO 抽象层 观察者
public interface Observer {
// 被观察者改变了,我这里可以知道
void update(Object value);
}
// 被观察者实现
public class ServerObservable implements Observable{
// 容器 存储 多个 观察者
private List<Observer> observers = new ArrayList<>();
//消息
private String message;
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
//遍历容器
for (Observer observer : observers) {
observer.update(message);
}
}
@Override
public void pushMessage(String message) {
//发布消息就通知改变
this.message = message;
System.out.println("更新了消息:" + message);
//通知改变
notifyObservers();
}
}
public class UserPerson implements Observer{
private String name;
private String message;
public UserPerson(String name) {
this.name = name;
}
@Override
public void update(Object value) {
this.message = (String) value;
// 读取消息
readMessage();
}
private void readMessage() {
System.out.println(name + " 收到了推送消息:" + message);
}
}
/**
* TODO 主要是标准观察者模式
*
* TODO 使用场景例子
* 服务不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test();
}
public static void test() {
// 编辑部 编辑好的文案内容
String msg = "消息:以后Android程序员必须要学习Kotlin";
// 创建一个公众号服务(被观察者)
Observable server = new ServerObservable();
// 创建 用户 观察者)多个
Observer A = new UserPerson("A");
Observer B = new UserPerson("B");
Observer C = new UserPerson("C");
Observer D = new UserPerson("D");
// 订阅 注意:这里的订阅还是 被观察者.订阅(观察者) 关注
server.addObserver(A);
server.addObserver(B);
server.addObserver(C);
server.addObserver(D);
// 微信平台 发生了 改变
server.pushMessage(msg);
// B取消了关注
System.out.println("=============================================================");
server.removeObserver(B);
// 再次微信平台 发生了 改变
server.pushMessage(msg);
}
}
I/System.out: 更新了消息:消息:以后Android程序员必须要学习Kotlin
A 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
B 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
C 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
D 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
=============================================================
更新了消息:消息:以后Android程序员必须要学习Kotlin
A 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
C 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
D 收到了推送消息:消息:以后Android程序员必须要学习Kotlin
2.RxJava的 Hook 点
在代码的执行过程中,hook机制钩子程序,把执行的代码勾出来,先执行我的再执行你的
对整个RxJava做监听
@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));
}
ObjectHelper.requireNonNull(source, “source is null”); 检验是否为空,空的话抛出异常
new ObservableCreate(source) ; new 一个ObservableCreate 出来
.onAssembly 全局RxJava hook
map函数也是如此:
@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));
}
查看onAssembly函数:
@NonNull
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;
}
onObservableAssembly 默认为null 不进入if语句
new出来后丢进onAssembly,再直接返回
红色区域是废代码,不会执行,我们要想办法去执行:
自己搞一个hook出来,new一个Function让它不为null,就会先执行我们的代码
onObservableAssembly 只有一个地方可以赋值 :
@Nullable
static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;
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之前的监听
//new 了一个Function 部位null了
RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
@Override
public Observable apply(Observable observable) throws Exception {
Log.d(Flag.TAG, "apply: 整个项目全局监听到底有多少地方使用 RxJava:" + observable);
// 伪代码 做破坏只要返回null
/*if (observable === ObservableMap)
return null; 相当于 null.map */
return observable; // 不破坏人家的功能
}
});
testHook();
}
/**
* TODO RxJava Hook 点
*/
public static void testHook() {
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
e.onNext("A");
}
})
// null.map
.map(new Function<Object, Boolean>() {
@Override
public Boolean apply(Object o) throws Exception {
return true;
}
})
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
}
}) ;
}
}
apply: 整个项目全局监听到底有多少地方使用 RxJava:io.reactivex.internal.operators.observable.ObservableCreate@f9a8a6e
apply: 整个项目全局监听到底有多少地方使用 RxJava:io.reactivex.internal.operators.observable.ObservableMap@a0ea50f
结论:
很多很多操作符 都会经过 【onAssembly监听】
二.RxJava的观察者模式
1.创建Observable
2.创建Observer
3.使用subcribe()订阅
1.先看 Observer 源码 ,就是new了一个接口 直接来实现
// 取名自定义观察者
// 1:Observer 源码看看
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
}
public interface Observer<T> {
//一订阅先执行这个函数
void onSubscribe(@NonNull Disposable d);
//拿到上一个卡片流下来的数据
void onNext(@NonNull T t); //泛型 传什么就是什么
//拿到上一个卡片流下来错误的数据
void onError(@NonNull Throwable e);
//事件结束
void onComplete();
}
2.Observable创建过程 源码分析
把自定义source传入到 Observable.create()里面
// 2:Observable创建过程 源码分析
Observable.create(
// 自定义source
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 发射器.onNext
emitter.onNext("A");
}
}
)
自定义source传入到 Observable.create() 里面后,检验是否为空,不空没问题后 new ObservableCreate(source)
自定义source 丢到了 new ObservableCreate() 里面
@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));
}
final ObservableOnSubscribe<T> source;//自定义source存在这里
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
结论:
new ObservableCreate() {source == 自定义source}
3.使用subcribe()订阅
Observable.create()返回一个ObservableCreate对象
ObservableCreate. subscribe
// 3:subscribe订阅过程 源码分析
// ObservableCreate. subscribe
.subscribe()
subscribe源码:
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
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(observer);以上都是校验
subscribeActual源码:
protected abstract void subscribeActual(Observer<? super T> observer);
是一个抽象函数
因为是 ObservableCreate. subscribe
所以subscribeActual(observer); 调用的是ObservableCreate里面的subscribeActual (自定义观察者):
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
4.逻辑图
subscribeActual (自定义观察者):
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
CreateEmitter parent = new CreateEmitter(observer);
new 了一个发射器,把自定义观察者放进去
observer.onSubscribe(parent);
一订阅马上执行onSubscribe ----------底端
source.subscribe(parent);
自定义source.subscribe(自定义的发射器)
回到了顶端
// 自定义source
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
// 发射器.onNext
emitter.onNext("A");
}
}
emitter.onNext(“A”);
发射器.onNext()
5.两者对比(标准的观察者设计模式与RxJava观察者设计模式)
在标准的观察者设计模式中,是一个“被观察者”,多个“观察者“,并且需要“被观察者”发出改变通知后,所有的”观察者”才能观察到
RxJava:
在RxJava观察者设计模式中,是多个“被观察者”,一个“观察者”,并且需要 起点 和 终点 在 “订阅” 一次后,才发出改变通知,终点(观察者)才能观察到
最后.subscribe()里面只有一个自定义观察者
可以添加多个map,map的本质是Observable
@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的本质是Observable
@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));
}
可以有多个被观察者,只能有一个观察者
严格称为发布订阅模式
还有好处就是添加map: