RXJava源码详解

rxjava

Rx介绍

ReactiveX的历史

ReactiveX是Reactive Extensions的缩写,一般简写为Rx,最初是LINQ的一个扩展,由微软的架构师Erik Meijer领导的团队开发,在2012年11月开源,Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx库支持.NET、JavaScript和C++,Rx近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,Rx的大部分语言库由ReactiveX这个组织负责维护,比较流行的有RxJava/RxJS/Rx.NET,社区网站是 reactivex.io

什么是ReactiveX

微软给的定义是,Rx是一个函数库,让开发者可以利用可观察序列和LINQ风格查询操作符来编写异步和基于事件的程序,使用Rx,开发者可以用Observables表示异步数据流,用LINQ操作符查询异步数据流, 用Schedulers参数化异步数据流的并发处理,Rx可以这样定义:Rx = Observables + LINQ + Schedulers。

ReactiveX.io给的定义是,Rx是一个使用可观察数据流进行异步编程的编程接口,ReactiveX结合了观察者模式、迭代器模式和函数式编程的精华。

ReactiveX的应用

很多公司都在使用ReactiveX,例如Microsoft、Netflix、Github、Trello、SoundCloud。

ReactiveX宣言

ReactiveX不仅仅是一个编程接口,它是一种编程思想的突破,它影响了许多其它的程序库和框架以及编程语言。

Rx模式

使用观察者模式

  • 创建:Rx可以方便的创建事件流和数据流

  • 组合:Rx使用查询式的操作符组合和变换数据流

  • 监听:Rx可以订阅任何可观察的数据流并执行操作

简化代码

  • 函数式风格:对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态

  • 简化代码:Rx的操作符通通常可以将复杂的难题简化为很少的几行代码

  • 异步错误处理:传统的try/catch没办法处理异步计算,Rx提供了合适的错误处理机制

  • 轻松使用并发:Rx的Observables和Schedulers让开发者可以摆脱底层的线程同步和各种并发问题

使用Observable的优势

Rx扩展了观察者模式用于支持数据和事件序列,添加了一些操作符,它让你可以声明式的组合这些序列,而无需关注底层的实现:如线程、同步、线程安全、并发数据结构和非阻塞IO。

Observable通过使用最佳的方式访问异步数据序列填补了这个间隙

 

Observable无偏见

Rx对于对于并发性或异步性没有任何特殊的偏好,Observable可以用任何方式实现,线程池、事件循环、非阻塞IO、Actor模式,任何满足你的需求的,你擅长或偏好的方式都可以。无论你选择怎样实现它,无论底层实现是阻塞的还是非阻塞的,客户端代码将所有与Observable的交互都当做是异步的

响应式编程

Rx提供了一系列的操作符,你可以使用它们来过滤(filter)、选择(select)、变换(transform)、结合(combine)和组合(compose)多个Observable,这些操作符让执行和复合变得非常高效。

你可以把Observable当做Iterable的推送方式的等价物,使用Iterable,消费者从生产者那拉取数据,线程阻塞直至数据准备好。使用Observable,在数据准备好时,生产者将数据推送给消费者。数据可以同步或异步的到达,这种方式更灵活。

入门链接:

https://www.jianshu.com/p/cd3557b1a474

https://www.cnblogs.com/lyysz/p/6344507.html

https://www.cnblogs.com/liushilin/p/7058302.html

https://www.jb51.net/article/92309.html 

https://zhuanlan.zhihu.com/p/31413825

rxjava2.0与3.0差异化

https://blog.csdn.net/weixin_45258969/article/details/95386872?utm_medium=distribute.down_relevant_right.none-task-blog-BlogCommendFromBaidu-1.nonecase&depth_1-utm_source=distribute.down_relevant_right.none-task-blog-BlogCommendFromBaidu-1.nonecase

基本使用

最基本的使用

 Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("连载1");
                emitter.onNext("连载2");
                emitter.onNext("连载3");
                emitter.onComplete();
            }
        })
                .observeOn(AndroidSchedulers.mainThread())//回调在主线程
                .subscribeOn(Schedulers.io())//执行在io线程
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG,"onSubscribe");
                    }

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

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG,"onError="+e.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG,"onComplete()");
                    }
                });

使用Consumer省略多余的回调,只接受结束以后的,subscribeOn指定被观察者的线程,observeOn指定观察者的线程

Observable.create(new ObservableOnSubscribe<Drawable>() {
            @Override
            public void subscribe(ObservableEmitter<Drawable> emitter) throws Exception {
                for (int i=0;i<drawableRes.length;i++){
                    Drawable drawable=getResources().getDrawable(drawableRes[i]);
                    //第6个图片延时3秒后架子
                    if (i==5){
                        sleep(3000);
                    }
                    //复制第7张图片到sd卡
                    if (i==6){
                        Bitmap bitmap=((BitmapDrawable)drawable).getBitmap();
                        saveBitmap(bitmap,"test.png", Bitmap.CompressFormat.PNG);
                    }
                    //上传到网络
                    if (i==7){
                        updateIcon(drawable);
                    }
                    emitter.onNext(drawable);
                }
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Drawable>() {
                    @Override
                    public void accept(Drawable drawable) throws Exception {
                           //回调后在UI界面上展示出来
                    }
                });

RXJava配合Retrofit基本使用


public interface WangAndroidApi {

    // 总数据
    @GET("project/tree/json")
    Observable<ProjectBean> getProject();  // 异步线程 耗时操作

    // ITem数据
    @GET("project/list/{pageIndex}/json") // ?cid=294
    Observable<ProjectItem> getProjectItem(@Path("pageIndex") int pageIndex, @Query("cid") int cid);  // 异步线程 耗时操作
}
  /**
     * TODO Retrofit+RxJava 查询 项目分类  (总数据查询)
     *
     * @param view
     */
    public void getProjectAction(View view) {
        // 获取网络API
        api.getProject()
                .subscribeOn(Schedulers.io()) // 上面 异步
                .observeOn(AndroidSchedulers.mainThread()) // 下面 主线程
                .subscribe(new Consumer<ProjectBean>() {
                    @Override
                    public void accept(ProjectBean projectBean) throws Exception {
                        Log.d(TAG, "accept: " + projectBean); // UI 可以做事情
                    }
                });
    }

 

防抖

使用RXView,进行防抖的操作

过度嵌套的操作

 // 注意:(项目分类)查询的id,通过此id再去查询(项目列表数据)

        // 对那个控件防抖动?
        Button bt_anti_shake = findViewById(R.id.bt_anti_shake);

        RxView.clicks(bt_anti_shake)
                .throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应你一次
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        api.getProject() // 查询主数据
                        .compose(DownloadActivity.rxud())
                        .subscribe(new Consumer<ProjectBean>() {
                            @Override
                            public void accept(ProjectBean projectBean) throws Exception {
                                for (ProjectBean.DataBean dataBean : projectBean.getData()) { // 10
                                    // 查询item数据
                                    api.getProjectItem(1, dataBean.getId())
                                    .compose(DownloadActivity.rxud())
                                    .subscribe(new Consumer<ProjectItem>() {
                                        @Override
                                        public void accept(ProjectItem projectItem) throws Exception {
                                            Log.d(TAG, "accept: " + projectItem); // 可以UI操作
                                        }
                                    });
                                }
                            }
                        });
                    }
                });

使用flatmap的操作

 // 注意:项目分类查询的id,通过此id再去查询(项目列表数据)

        // 对那个控件防抖动?
        Button bt_anti_shake = findViewById(R.id.bt_anti_shake);

        RxView.clicks(bt_anti_shake)
                .throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应你一次

                // 我只给下面 切换 异步
                .observeOn(Schedulers.io())
                .flatMap(new Function<Object, ObservableSource<ProjectBean>>() {
                    @Override
                    public ObservableSource<ProjectBean> apply(Object o) throws Exception {
                        return api.getProject(); // 主数据
                    }
                })

                // 第一步不能map 因为  api Observbale<Bean>  TODO 小作业 同学们自己尝试
                /*.map(new Function<Object, ObservableSource<ProjectBean>>() {
                    @Override
                    public ObservableSource<ProjectBean> apply(Object o) throws Exception {
                        return api.getProject(); // 主数据;
                    }
                })*/

                .flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataBean>>() {
                    @Override
                    public ObservableSource<ProjectBean.DataBean> apply(ProjectBean projectBean) throws Exception {
                        return Observable.fromIterable(projectBean.getData()); // 我自己搞一个发射器 发多次 10
                    }
                })
                .flatMap(new Function<ProjectBean.DataBean, ObservableSource<ProjectItem>>() {
                    @Override
                    public ObservableSource<ProjectItem> apply(ProjectBean.DataBean dataBean) throws Exception {
                        return api.getProjectItem(1, dataBean.getId());
                    }
                })

                .observeOn(AndroidSchedulers.mainThread()) // 给下面切换 主线程
                .subscribe(new Consumer<ProjectItem>() {
                    @Override
                    public void accept(ProjectItem projectItem) throws Exception {
                        // 如果我要更新UI  会报错2  不会报错1
                        Log.d(TAG, "accept: " + projectItem);
                    }
                });

doOnNext

doOnNext()允许我们在每次输出一个元素之前做一些额外的事情。比如如下的例子,在第一个注册完成之后,调用deOnNext进行插入操作,然后在进行最后的subscribe操作,相当于插入了操作.

/**
 * TODO
 *  Retrofit + RxJava
 *  需求:
 *  1.请求服务器注册操作
 *  2.注册完成之后,更新注册UI
 *  3.马上去登录服务器操作
 *  4.登录完成之后,更新登录的UI
 *
 * wy.RxJava配合Retrofit。
 * RxJava + Retrofit (请求网络OkHttp  ---- Retorfit  --- Observable)
 *
 * 1.OkHttp 请求网络 (Retorfit)
 * 2.Retorfit 返回一个结果 (Retorfit) --- Observable
 * 3.最终的结果 是RxJava中的 被观察者 上游 Observable
 * 4.一行代码写完需求流程: 从上往下
 *    1.请求服务器,执行注册操作(耗时)切换异步线程
 *    2.更新注册后的所有 注册相关UI - main  切换主线程
 *    3.请求服务器,执行登录操作(耗时)切换异步线程
 *    4.更新登录后的所有 登录相关UI - main  切换主线程
 *
 * 5.看RxJava另外一种的执行流程
 *   初始点 开始点 订阅
 *   1.onSubscribe
 *   2.registerAction(new RegisterRequest())
 *   3..doOnNext 更新注册后的 所有UI
 *   4.flatMap执行登录的耗时操作
 *   5.订阅的观察者 下游 onNext 方法,更新所有登录后的UI
 *   6.progressDialog.dismiss()
 */
public class RequestActivity extends AppCompatActivity {

    private final String TAG = RequestActivity.class.getSimpleName();

    private TextView tv_register_ui;
    private TextView tv_login_ui;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_request);

        tv_register_ui = findViewById(R.id.tv_login_ui);
        tv_login_ui = findViewById(R.id.tv_login_ui);

    }

    // TODO 方式一 分开写
    @SuppressLint("CheckResult")
    public void request(View view) {
        // 1.请求服务器注册操作
        // 2.注册完成之后,更新注册UI
        MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                .registerAction(new RegisterRequest())
                .compose(DownloadActivity.rxud())
                .subscribe(new Consumer<RegisterResponse>() {
                    @Override
                    public void accept(RegisterResponse registerResponse) throws Exception {
                        // 更新注册相关的所有UI
                        // .....
                    }
                });

        // 分开写

        // 3.马上去登录服务器操作
        // 4.登录完成之后,更新登录的UI
        MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                .loginAction(new LoginReqeust())
                .compose(DownloadActivity.rxud())
                .subscribe(new Consumer<LoginResponse>() {
                    @Override
                    public void accept(LoginResponse loginResponse) throws Exception {
                        // 更新登录相关的所有UI
                        // .....
                    }
                });
    }


    /**
     * TODO ================= 下面是一行代码完成整个需求
     */

    private ProgressDialog progressDialog;
    Disposable disposable;

    public void request2(View view) {

        /**
         * 一行代码 实现需求
         * 需求:
         *   还有弹出加载
         *  * 1.请求服务器注册操作
         *  * 2.注册完成之后,更新注册UI
         *  * 3.马上去登录服务器操作
         *  * 4.登录完成之后,更新登录的UI
         */
        MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                .registerAction(new RegisterRequest()) // todo 1.请求服务器注册操作   // todo 2
                .subscribeOn(Schedulers.io()) // 给上面 异步
                .observeOn(AndroidSchedulers.mainThread()) // 给下面分配主线程
                .doOnNext(new Consumer<RegisterResponse>() { // todo 3
                    @Override
                    public void accept(RegisterResponse registerResponse) throws Exception {
                        // todo 2.注册完成之后,更新注册UI
                    }
                })
                // todo 3.马上去登录服务器操作
                .observeOn(Schedulers.io()) // 给下面分配了异步线程
                .flatMap(new Function<RegisterResponse, ObservableSource<LoginResponse>>() { // todo 4
                    @Override
                    public ObservableSource<LoginResponse> apply(RegisterResponse registerResponse) throws Exception {
                        Observable<LoginResponse> loginResponseObservable = MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                                .loginAction(new LoginReqeust());
                        return loginResponseObservable;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) // 给下面 执行主线程
                .subscribe(new Observer<LoginResponse>() {

                    // 一定是主线程,为什么,因为 subscribe 马上调用onSubscribe
                    @Override
                    public void onSubscribe(Disposable d) {
                        // TODO 1
                        progressDialog = new ProgressDialog(RequestActivity.this);
                        progressDialog.show();

                        // UI 操作

                        disposable = d;
                    }

                    @Override
                    public void onNext(LoginResponse loginResponse) { // todo 5
                        // TODO 4.登录完成之后,更新登录的UI
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    // todo 6
                    @Override
                    public void onComplete() {
                        // 杀青了
                        if (progressDialog != null) {
                            progressDialog.dismiss();
                        }
                    }
                });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 必须这样写,最起码的标准
        if (disposable != null)
            if (!disposable.isDisposed())
                disposable.dispose();
    }
}

 

 

RXJAVA源码解析

首先了解一下如何hook rxjava,上图

hook方法,可以hook住所有的observable

   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; // 不破坏人家的功能
            }
        });

那么为什么可以hook住呢

observable提供了一个回调函数,将监听赋给了onObservableAssembly 

  @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;
    }

在起初create的时候,有一个RxJavaPlugins的方法,调用了onAssembly

  @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));
    }

然后调用到这里,apply里面监听使用了onObservableAssembly.apply,然后就可以开心回调啦。可以用于调试hook了啥

 @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;
    }

 @NonNull
    static <T, R> R apply(@NonNull Function<T, R> f, @NonNull T t) {
        try {
            return f.apply(t);
        } catch (Throwable ex) {
            throw ExceptionHelper.wrapOrThrow(ex);
        }
    }

下面正式分析怎么实现响应式编程的:

RxJava的观察者模式,rxjava并不是严格的观察者模式,普通的观察者模式一般是由被观察者订阅观察者,(简单的一个例子,被观察者内部持有保存了观察者的引用,一旦被观察者发出消息,便可以统一发送消息)

在rxjava里面是一个u形的线式调用,先逐步订阅,然后在一次调用onNext完成整个流程

1、先了解一下订阅流程:上图

一、最简单的情况

 Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                e.onNext("A");
            }
        })

.subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                
            }

            @Override
            public void onNext(@NonNull Boolean aBoolean) {

            }

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

            }

            @Override
            public void onComplete() {

            }
        })   ;

从create开始,最后其实就是返回了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));
    }

    @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;
    }

来看一下这个对象,我们先记住subscribeActual这个方法

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    @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);
        }
    }
    static final class CreateEmitter<T>
        extends AtomicReference<Disposable>
        implements ObservableEmitter<T>, Disposable{....}

    static final class SerializedEmitter<T>
        extends AtomicInteger
        implements ObservableEmitter<T>{.....}
}

在这个方法里使用了传入进来的observer调用了创建出来的发射器,

observer.onSubscribe(parent);那这个observer是谁呢?至此我们完成了create的订阅步骤。

我们知道了create出来的是一个ObservableCreate的对象,然后我们来看一下.subscribe干了什么

 @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final Disposable subscribe(Consumer<? super T> onNext) {
        return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION, Functions.emptyConsumer());
    }
  @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
            Action onComplete, Consumer<? super Disposable> onSubscribe) {
        ObjectHelper.requireNonNull(onNext, "onNext is null");
        ObjectHelper.requireNonNull(onError, "onError is null");
        ObjectHelper.requireNonNull(onComplete, "onComplete is null");
        ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");

        LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);

        subscribe(ls);//here

        return ls;
    }
 @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);//here
        } 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;
        }
    }
//调用了这个抽象方法
 protected abstract void subscribeActual(Observer<? super T> observer);

这里面调用了抽象方法subscribeActual,而.subscribe又是由ObservableCreate对象调用的的,ObservableCreate继承了Observable,所以也就调用了我们之前看到的subscribeActual方法。

原来直到使用.subscribe的时候才触发了这个方法,远远在订阅完成之后的,那这个时候就知道了subscribeActual里面的observer是谁了吧,就是create里面传进来的观察者

.subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                //一订阅就调用
            }

            @Override
            public void onNext(@NonNull Boolean aBoolean) {
                //最后会回到这里
            }

            @Override
            public void onError(@NonNull Throwable e) {
                //报错
            }

            @Override
            public void onComplete() {
                //事件结束
            }
        })   ;

所以订阅调用create就会首先调用onSubscribe的方法

再回到ObservableCreate类里面,触发了onSubscribe方法之后调用了

   source.subscribe(parent);

parent就是一开始create传进来的对象,由此回调到了这里来进行操作分发,返回的参数就是创建的发射器,如果我们调用一下e.onNext,就可以将数据向下发射了。

 Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                e.onNext("A");
            }
        })

发射的方法,在ObservableCreate,有发射的类,看一下调到了哪里

   static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {


        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {
            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            if (!isDisposed()) {
                observer.onNext(t);///here
            }
        }

        @Override
        public void onError(Throwable t) {
            if (!tryOnError(t)) {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public boolean tryOnError(Throwable t) {
            if (t == null) {
                t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
            }
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose();
                }
                return true;
            }
            return false;
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }
        }
}

还记得吗,这里的observer是subscribeActual传进来的,是.subscribe(new Observer<Boolean>() )中的对象

  observer.onNext(t)的方法一调用,就会回调到我们的主线程里面了,完成了下发

总结起来就是在调用subscribe之前,我们只是创建了create的订阅,相当于从上游(被观察者)走向了下游(观察者)。调用了subscribe这个方法之后,回调了下游的方法,完成监听并发射数据之后,触发了上游的对象

最终完成了数据的响应式编程,u形结构,可以说和观察者模式是有区别的

可以看作是不断新建上游的被观察者来操纵数据,最后反馈给上由一个观察者,属于多个被观察者和一个观察者(Observer),观察者模式是一个被观察者,多个观察者

 

 

二,稍微复杂的情况

完成create的分析,下面增加难度,新增一个map

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 Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Boolean aBoolean) {

            }

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

            }

            @Override
            public void onComplete() {

            }
        })   ;

来分析一下map干了些什么,首先要明白是谁调用的map,要记得,是ObservableOnSubscribe对象,然后点进去看一下,还是那个熟悉的味道,最终返回的是ObservableMap对象,一样的套路

 @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));
    }

这里面还是有一个熟悉的方法subscribeActual

至此,完成了被观察者ObservableMap的订阅

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));
    }


    static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {...}
}

然后我们和第一部分的代码一起来走一遍流程,是怎么调用的

1、创建ObservableOnSubscribe订阅

2、创建ObservableMap订阅

3、当我们开始使用.subscribe进行订阅的时候,这个时候是离得最近的ObservableMap调用了subscribe开始订阅,触发subscribe方法里面的

protected abstract void subscribeActual(Observer<? super T> observer);

也就是触发了ObservableMap的subscribeActual,我们发现没有做什么,就是使用MapObserver打包了一下,然后讲打包一起丢给了这个source的方法

    @Override
    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }

看一下这个包装了什么,调用了apply,也就是我们在主流程里面回调的方法.,在这里实现了,调用完成后触发onNext,onNext是subscribeActual传进来的,也就是最终观察者的onNext完成的状态,但是在这之前,因为我们有source的调用,所以在这里是先走了source的方法,那么source是啥呢

static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }

        @Override
        public void onNext(T t) {
       if (done) {
                return;
            }

            if (sourceMode != NONE) {
                actual.onNext(null);
                return;
            }

            U v;

            try {
                v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            actual.onNext(v);

        }
   }

 

还记得这个source吗,这个是ObservableMap初始化带进来的,这个this,就是调用map的ObservableOnSubscribe,走到这里又走回去开始调用ObservableOnSubscribe的方法了

  @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));
    }

 

ObservableOnSubscribe继承自Observable的,自己没有这个方法,就调用了父类Observable的,这个时候实际上就回到了第一步的流程了,开始调用ObservableCreate,以及其下的方法

@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;
        }
    }

 

但是呢,第一大部分里面我们是最终的观察者来发起的订阅触发的ObservableOnSubscribe,而这里却是ObservableMap,所以触发的也是ObservableMap的onNext,往上翻一下,看一下MapObserver的onNext是不是开始调用最终观察者的onNext了,

4、经过了订阅ObservableOnSubscribe----ObservableMap-----Observer.subscribe------ObservableMap.subscribeActual-----ObservableOnSubscribe.subscribeActual------ObservableOnSubscribe的onNext--ObservableMap的onNext---Observer的onNext终于完成了整个调用链条

再看一下一开始贴的流程图,是不是很清晰的u形调用逻辑,至此.基本的调用链条走完了,累......

 

三、切换线程的分析

对于我们Android开发来说,最喜欢的就是它简洁切换线程的操作。RxJava通过调度器来方便线程的切换。

  • Schedulers.computation(): 适合运行在密集计算的操作,大多数异步操作符使用该调度器。
  • Schedulers.io():适合运行I/0和阻塞操作.
  • Schedulers.single():适合需要单一线程的操作
  • Schedulers.trampoline(): 适合需要顺序运行的操作
  • 在不同平台还有不同的调度器,例如Android的主线程:AndroidSchedulers.mainThread()

我们在使用期间会使用observeOn以及subsceOn来实现线程的切换调度,不断地在主线程和子线程切换,这玩意儿是咋做到的呢

我先贴个链接,了解了以后可以再看一下

为什么subscribeOn第一次执行生效,observeOn每次执行都生效?

然后上图

subscribeOn

  Observable.create(

                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        e.onNext("Derry");

                        Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe();
)

 @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

点进来看看,这是啥,是不是还是那一套,这里是订阅了ObservableSubscribeOn,

这里再看一下observeOn,对那个是ObservableObserveOn,名字很像,不要整混了.

   @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }
   @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
    }

其实就是在这两个被观察者里面实现的线程的切换,还记得开始的时候抛出的问题么,为什么连续调用几个方法的时候,二者触发的流程不一样(为什么subscribeOn第一次执行生效,observeOn每次执行都生效?)

// subsceOn(1)  // 会显示是这个线程的原因,上一层卡片是被1线程执行
// subsceOn(2)
// subsceOn(3)

// observeOn(A)
// observeOn(B)
// observeOn(C) // 终点是被C执行

来看一下二者源码

看到了吗.ObservableSubscribeOn的切换执行是在subscribeActual里面进行切换的,SubscribeTask就是一个Runnable,内部是使用线程池进行线程的切换,

而subscribeActual是在自下而上触发subscribeActual的时候切换的,所以从下而上,第一个才是实际切换的线程

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> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);

        s.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));//在这就开始线程的切换了
    }

    static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {

        private static final long serialVersionUID = 8094547886072529208L;
        final Observer<? super T> actual;

        final AtomicReference<Disposable> s;

        SubscribeOnObserver(Observer<? super T> actual) {
            this.actual = actual;
            this.s = new AtomicReference<Disposable>();
        }

        @Override
        public void onSubscribe(Disposable s) {
            DisposableHelper.setOnce(this.s, s);
        }

        @Override
        public void onNext(T t) {
            actual.onNext(t);
        }

        @Override
        public void onError(Throwable t) {
            actual.onError(t);
        }

        @Override
        public void onComplete() {
            actual.onComplete();
        }

        @Override
        public void dispose() {
            DisposableHelper.dispose(s);
            DisposableHelper.dispose(this);
        }

        @Override
        public boolean isDisposed() {
            return DisposableHelper.isDisposed(get());
        }

        void setDisposable(Disposable d) {
            DisposableHelper.setOnce(this, d);
        }
    }

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            source.subscribe(parent);
        }
    }
}

 

而在ObservableObserveOn的方法里subscribeActual只是创建了线程调度的Scheduler.Worker w = scheduler.createWorker();

直到onNext里面 schedule()方法才开始执行线程的切换,以后每一步onNext都会在新切换的线程执行,所以会执行最后一个的切换,只要整个流程弄明白了,这里就很容易理解

多说一句,这里执行的是切换主线程的操作的时候使用的是handler切换的主线程

 new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);

                // UI 操作 ...
            }
        };
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;
    }

    @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<T>(observer, w, delayError, bufferSize));
        }
    }

    static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    implements Observer<T>, Runnable {

         .......
        ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
            this.actual = actual;
            this.worker = worker;
            this.delayError = delayError;
            this.bufferSize = bufferSize;
        }

        @Override
        public void onSubscribe(Disposable s) {
            if (DisposableHelper.validate(this.s, s)) {
                this.s = s;
                if (s instanceof QueueDisposable) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable<T> qd = (QueueDisposable<T>) s;

                    int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);

                    if (m == QueueDisposable.SYNC) {
                        sourceMode = m;
                        queue = qd;
                        done = true;
                        actual.onSubscribe(this);
                        schedule();
                        return;
                    }
                    if (m == QueueDisposable.ASYNC) {
                        sourceMode = m;
                        queue = qd;
                        actual.onSubscribe(this);
                        return;
                    }
                }

                queue = new SpscLinkedArrayQueue<T>(bufferSize);

                actual.onSubscribe(this);
            }
        }

        @Override
        public void onNext(T t) {
            if (done) {
                return;
            }

            if (sourceMode != QueueDisposable.ASYNC) {
                queue.offer(t);
            }
            schedule();here
        }

        @Override
        public void onError(Throwable t) {
            if (done) {
                RxJavaPlugins.onError(t);
                return;
            }
            error = t;
            done = true;
            schedule();
        }

        @Override
        public void onComplete() {
            if (done) {
                return;
            }
            done = true;
            schedule();
        }

        @Override
        public void dispose() {
            if (!cancelled) {
                cancelled = true;
                s.dispose();
                worker.dispose();
                if (getAndIncrement() == 0) {
                    queue.clear();
                }
            }
        }

        @Override
        public boolean isDisposed() {
            return cancelled;
        }

        void schedule() {
            if (getAndIncrement() == 0) {
                worker.schedule(this);
            }
        }
}

所以什么是rxjava呢,这种响应式的编程,在其间使用装饰模式的概念,创建了一个又一个的ObservableXXX类来实现具体的被观察者,将数据层层包裹处理,又利用了观察者模式的思路实现了多个被观察者对观察者数据发送,,一环扣一环

 

观察者模式与发布订阅模式

装饰模型

全剧终....

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值