RxJava模式与原理-----标准观察者与RxJava观察者

7 篇文章 0 订阅

一.标准观察者

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:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值