十七、RxJava篇(RxJava模式与原理)

一、前言

之前我们说 RxJava是基于起点到终点,之间通过一条线连接,这条线里我们可以做相应的拦截操作的这种编程思维。其实在规范的称呼中RxJava是基于观察者设计模式的一种响应式编程思维。从RxJava两个关键对象就可以看到Observable是我们的被观察者、Observer是我们的观察者。Observer通过观察Observable的数据变换做出响应,然而又说RxJava使用的不是标准的观察者设计模式。

二、观察者设计模式

什么是观察者设计模式?
如下图,我们有一个微信公众号,公众号可以定时更新文章并推送给关注的用户。A和B用户关注了公众号,当公众号更新文章的时候A和B收到了相应的推送。在这里我们的公众号就是一个被观察者,A和B用户就是观察者。当公众号更新消息推送的时候,A和B就可以通过观察收到消息。


  • 通过代码实现
    (1)创建被观察者
package com.example.andoiddemo;

/**
 * 被观察者接口
 */
public interface Observable {
    void addUser(Observer user);

    void removeUser(Observer user);

    void pushMessage(String msg);
}

package com.example.andoiddemo;


import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class WeChatObservable implements Observable {
    private static final String TAG ="WeChatObservable" ;
    private List<Observer> list = new ArrayList<>();
    @Override
    public void addUser(Observer user) {
        list.add(user);
    }
    @Override
    public void removeUser(Observer user) {
        list.remove(user);
    }

    @Override
    public void pushMessage(String msg) {
        Log.e(TAG, "观察者推送了一条消息: "+msg );
        for (int i = 0; i <list.size() ; i++) {
            list.get(i).receiveMessage(msg);
        }
    }
}

(2)创建观察者A和B

package com.example.andoiddemo;

/**
 * 观察者
 */
public interface Observer {


    /**
     * 收到消息
     * @param msg
     */
    void receiveMessage(String msg);
}

package com.example.andoiddemo;

import android.util.Log;

public class AUserObserver implements Observer {
    private static final String TAG = "AUserObserver";

    @Override
    public void receiveMessage(String msg) {
        Log.e(TAG, "A用户收到了消息: "+msg );
    }
}

package com.example.andoiddemo;

import android.util.Log;

public class BUserObserver implements Observer {
    private static final String TAG = "BUserObserver";

    @Override
    public void receiveMessage(String msg) {
        Log.e(TAG, "B用户收到了消息: "+msg );
    }
}

(3)测试

    private void test7() {
        com.example.andoiddemo.Observer a = new com.example.andoiddemo.AUserObserver();
        com.example.andoiddemo.Observer b = new com.example.andoiddemo.BUserObserver();
        com.example.andoiddemo.Observable observable = new WeChatObservable();
        //添加关注
        observable.addUser(a);
        observable.addUser(b);
        observable.pushMessage("hello world");
        //移除关注
        observable.removeUser(b);
        observable.pushMessage("你好世界");
    }
2021-06-08 18:00:39.229 25088-25088/com.example.andoiddemo E/WeChatObservable: 观察者推送了一条消息: hello world
2021-06-08 18:00:39.229 25088-25088/com.example.andoiddemo E/AUserObserver: A用户收到了消息: hello world
2021-06-08 18:00:39.229 25088-25088/com.example.andoiddemo E/BUserObserver: B用户收到了消息: hello world
2021-06-08 18:00:39.229 25088-25088/com.example.andoiddemo E/WeChatObservable: 观察者推送了一条消息: 你好世界
2021-06-08 18:00:39.229 25088-25088/com.example.andoiddemo E/AUserObserver: A用户收到了消息: 你好世界

通过以上的代码我们发现,观察者设计模式的核心就是被观察者对象中有一个容器,这个容器包含了观察者对象。当观察者数据更新的时候,再通过容器中拿到被观察者对象然后通知他们,这样一来观察者就收到了数据更新。再标准的观察者设计模式中,这里被观察者只有一个,观察者可以有多个。

三、观察者设计模式与RxJava对比

以上我们知道在标准的观察者设计模式中,被观察者只有一个,而观察者可以有多个。而我们再来看看RxJava的代码。

  private void test8() {
        Observable.just("hello world").map(new Function<String, String>() {
            @Override
            public String apply(@NonNull String s) throws Exception {
                return s;
            }
        }).map(new Function<String, String>() {
            @Override
            public String apply(@NonNull String s) throws Exception {
                return s;
            }
        }).map(new Function<String, String>() {
            @Override
            public String apply(@NonNull String s) throws Exception {
                return s;
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull String s) {
                Log.e(TAG, "onNext: "+s );
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

在test8的方法中我们看到Observable被观察者通过just输入一个事件,然后调用了3次map,每一次map操作都返回一个被观察者,这样就将事件依次变换传递给下面的被观察者。而我们的观察者要接收事件做出响应,必须要通过subscribe进行订阅,并且观察者响应的是最后一个被观察者的事件。这里就和标准的观察者模式有所区别。

  • 标准的观察者模式,被观察者只有一个,观察者可以有多个,当被观察者发出事件的时候,所有添加的观察者都能收到事件。
  • RxJava中的观察者设计模式,被观察者可以有多个,观察者只有一个,两者之间通过订阅进行关联。并且观察者只接受最后一个被观察者的事件。

四、RxJava事件发射以及map事件变换原理

1、事件发射

2、map事件变换

五、线程切换原理

1、subscribeOn(Schedulers.io())

讲当前运行环境切换到Io线程,其实就子线程。原理就是将我们observer封装成runnable对象,由线程池执行。


2、observeOn(AndroidSchedulers.mainThread())

将下面的代码切换到主线程。原理就是ObservableObserveOn调用subscribe的时候本来应该是调用onNext 讲事件往下发射,但是它是先通过Handler进行线程的切换


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章