RXJava常用流程解析与手写RXJava


前言

现在有很多公司在用RXJava进行生产开发,但是呢,RXJava的源码过于生涩难懂,而且用法也很多,操作符也很多,因此本文手写一个精简版的RXJava,希望能够一起去探索,RXJava在安卓中的奥妙!注意:本篇读者需要对RXJava有一定的使用经验与对RXJava调用过程有一定的理解


一、RXJava常用写法

        io.reactivex.rxjava3.core.Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
               //被观察者产生事件
            }
        }).map(new Function<String, Integer>() {

            @Override
            public Integer apply(String s) throws Throwable {
                //事件的转换
                return null;
            }
        }).subscribeOn(Schedulers.io()).
                observeOn(AndroidSchedulers.mainThread()).
                        subscribe(new io.reactivex.rxjava3.core.Observer<Integer>() {
                            //观察者处理事件
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {
                                
                            }

                            @Override
                            public void onNext(@NonNull Integer integer) {

                            }

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

                            }

                            @Override
                            public void onComplete() {

                            }
                        });

我们可以看到上述的代码,用到的操作有create,map,subscribe,subscribeOn,observeOn这几个。那么我们直接去从源码角度去解析。

 public static <T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
        Objects.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
    }

很多人看到这里就是一脸懵逼,其实RXJava的很多操作符都是采用这种方式去实现的,我们可以注意到这个方法里里面new 了一个ObservableCreate<>(source)对象,其实呢,这个就相当于一个包装类,那么它包装了什么呢,我们看类的关系
在这里插入图片描述
可以看到,其实就是对Obserable进行了一层包装。返回的ObservableCreate对象我们可以先视为Obserable对象,这点很重要。
那么为什么要返回一个与Obserable相关的对象呢?原因就是RXJava采用的链式编程,想要通过.操作链式操作吗,那么返回的要么是本类的this指针,要么是new一个对象。而RXJava采用了后者,这样保持了操作层次间的隔阂,因为.后一个Obserable不知道.前一个Obserable具体进行了什么操作,这样就很有利于层次的隔离。
create操作简单来看,也就是返回了用户建立的Obserable对象的包装类,这里不明白的话我们可以看到手写RXJava的环节,在那里我们去除相关的包装操作,更加方便我们去理解。
map操作其实和create的形式差不多

    public final <R> Observable<R> map(@NonNull Function<? super T, ? extends R> mapper) {
        Objects.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap<>(this, mapper));
    }

点进去onAssembly里面看,不过map里面有自己需要处理的逻辑,就是转换这个操作

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

最终会调用用户自己写入的apply方法。因为RXJava只是提供一个模式给用户,不负责处理具体的逻辑。
其他的异步操作代码形式相同,不过却有着自己的实现逻辑,我们先不分析其他的,直接进入到手写RXJava的逻辑吧!

二、手写RXJava

通过之前的代码分析,我们应该有一个模糊的了解,就是RXJava的链式调用采用的是new一个对象返回,而不是简单返回this指针,因此我们有如下代码

这里建立一个被观察者类
public abstract class Observable<T> {
    /*
    该方法是模拟Rxjava中的create方法,实际上Rxjava是做了一层包装
     */
    public static <T> Observable<T> create(Observable<T> observable) {
    //用户给什么,我们就返回什么,就是这么任性
        return observable;
    }

    public abstract void subscribe(Observer<T> observer);

}
这里声明一个观察者接口,里面的方法实现由使用者自行设定
public interface Observer<T> {
    void onNext(T parms);
    void onComplete();
    void onError();
}

这样子,我们就已经是实现好了一个简单的create操作符,是不是很神奇

       //create方法
        Observable.create(new Observable<String>() {
            @Override
            public void subscribe(Observer<String> observer) {
                
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onNext(String parms) {
                
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onError() {

            }
        });

和RXJava一摸一样吧,能够实现这样的效果的原因就是用户重写的Observer方法会被事件分发的时候调用。请读者一定要理解这个过程,因为后面的操作符就是基于这个过程来实现的。

接下就是map操作符

设定一个数据转换接口,具体实现有用户实现
public interface Funtion<T,R> {
     R transform(T t);
}

    public <R> Observable<R> map(Funtion<T, R> funtion) {
        return new Observable<R>() {
            @Override
            public void subscribe(Observer<R> observer) {
                Observer<T> observerNext = new Observer<T>() {
                    @Override
                    public void onNext(T parms) {
                        R transform = funtion.transform(parms);
                        observer.onNext(transform);
                    }

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

                    @Override
                    public void onError() {
                        observer.onError();
                    }
                };
                //将本次创建的Observe给上一轮的OObservable
                Observable.this.subscribe(observerNext);
            }
        };
    }

这里的难点有3个
1.new Observable()作用是:因为RXJava也是采用new一个新对象的方式返回的,所以我们仿照这形式即可,上文也说到,其实操作符返回的类都是Observable的子类,进行了各自功能的包装,因此我们直接new一个返回即可。
2.observerNext是什么,其实就是new出来的Observable的观察者对象。这里有一个细节需要我们去注意,就是new出的Observable对象的public void subscribe(Observer observer)方法,其实这个方法涉及到了RXJava的流程,大致分为订阅、观察者上溯、事件分发三个过程,这里就不列举相关的图片了,太复杂没有必要列举。
大家只要知道,这个方法传过来的observer对象,就是我们实际调用的时候的observer对象
3.通过上面两点,我们Observable之间并没有完全建立联系,因为Observable有多个,我们new出来的就有,所以为了绑定关系,我们需要把本次创建的Observable所对应的observer传入到上次的Observable中,这个就叫作观察者上溯过程,所以才有Observable.this.subscribe(observerNext);这句代码,读者需要注意与.this.subscribe(observerNext)的区别,这个很重要。

这样子,我们就能够写出以下代码

      Observable.create(new Observable<String>() {
            @Override
            public void subscribe(Observer<String> observer) {
               
                observer.onNext("123");
                observer.onComplete();
            }
        }).map(new Funtion<String, Integer>() {
            @Override
            public Integer transform(String s) {
                return Integer.parseInt(s);
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onNext(Integer parms) {
               
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onError() {

            }
        });
    }

至于线程切换操作,我们可以直接new一个Thread,再这里面进行异步处理(实际的RXJava有自己的实现,我们这里只是设计模式的模拟,简单处理多线程),那么放在什么时候比较合适呢,放在观察者上溯前面就比较合适了,即Observable中的subscribe方法被调用的时候。如下:

  public Observable<T> subscribeOn() {
        return new Observable<T>() {
            @Override
            public void subscribe(final Observer<T> observer) {
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        Observer<T> observerNext = new Observer<T>() {
                            @Override
                            public void onNext(T parms) {
                                Log.i("ObservableTest", "Observable in " + Thread.currentThread().getName());
                                observer.onNext(parms);
                            }

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

                            @Override
                            public void onError() {
                                observer.onError();
                            }
                        };
                        //将本次创建的Observe给上一轮的OObservable
                        Observable.this.subscribe(observerNext);
                    }
                }.start();
            }
        };

代码是不是非常类似!那么切换回来主线程的时候呢?当然是在事件分发的时候调用啦,我们以onNext回调为例子,就有如下:

  public Observable<T> observeOn() {
        Handler handler=new Handler(Looper.getMainLooper());
        return new Observable<T>() {
            @Override
            public void subscribe(final Observer<T> observer) {
                Observer<T> observerNext = new Observer<T>() {
                    @Override
                    public void onNext(T parms) {
                         handler.post(new Runnable() {
                             @Override
                             public void run() {
                                 Log.i("ObservableTest", "Observable in " + Thread.currentThread().getName());
                                 observer.onNext(parms);
                             }
                         });

                    }

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

                    @Override
                    public void onError() {
                        observer.onError();
                    }
                };
                //将本次创建的Observe给上一轮的OObservable
                Observable.this.subscribe(observerNext);
            }


        };
    }

这里没有设定调度器,只是模拟RXJava设计,所以就有如下用法

Observable.create(new Observable<String>() {
            @Override
            public void subscribe(Observer<String> observer) {
                Log.i("ObservableTest", "Observable subscribe in " + Thread.currentThread().getName());
                observer.onNext("123");
                observer.onComplete();
            }
        }).map(new Funtion<String, Integer>() {
            @Override
            public Integer transform(String s) {
                return Integer.parseInt(s);
            }
        }).subscribeOn().observeOn().subscribe(new Observer<Integer>() {
            @Override
            public void onNext(Integer parms) {
                Log.i("ObservableTest", "MainActivity in " + Thread.currentThread().getName());
             Log.i("ObservableTest","MainActivity"+parms);
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onError() {

            }
        });

在这里插入图片描述
这样,一个完美的线程切换就完成啦!

总结

对于手写RXJava,需要各位看官们了解好之间的调用机制与对象机制,熟悉好RXJava的流程,再结合上述代码进行消化吸收噢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值