浅析RxJava

915 阅读4分钟

前言

今天给大家分享一些RxJava的小知识,由浅入深了地解一下它的工作流程。

操作符:

我们先看下几个操作符的简单使用

map:数据转换

   Observable.just(path)
                .map(new Function<StringInteger>() {
                    @Override
                    public Integer apply(String s) {
                        return 1;
                    }
                })
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        System.out.println("onSubscribe:" + d.toString());
                    }

Compose」使用自定义操作符:

定义
public static <UDObservableTransformer<UDUDredux() {
    return new ObservableTransformer<UDUD>() {
        @Override
        public @NonNull ObservableSource<UD> apply(@NonNull Observable<UD> upstream) {
            return upstream.map(new Function<UD, UD>() {
                @Override
                public UD apply(UD ud) throws Throwable {
                    System.out.println("监听到了");
                    return ud;
                }
            });
        }
    };
}
使用
     Observable.just(path)
                .map(new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        System.out.println("map");
                        return 1;
                    }
                })
                .compose(redux()) //使用自定义操作符
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        System.out.println("onSubscribe:");
                    }  

flatMap 转换

map可以一对一转换为任何数据,flatMap 只能转换为ObservableSource类型 ,可以一对一,一对多,多对多转换。

Observable.just(list)
        //遍历集合
        .flatMap(new Function<List<String>, ObservableSource<String>>() {
            @Override
            public ObservableSource<Stringapply(List<String> integer) {
                return Observable.fromIterable(integer);
            }
        })
        .subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                System.out.println("onSubscribe:");
            }
          
        // 数据变换
        Observable.just(path)
                .map(new Function<StringString>() {
                    @Override
                    public String apply(String s) throws Throwable {
                        return s + "测试";
                    }
                })
                .flatMap(new Function<StringObservableSource<String>>() {
                    @Override
                    public ObservableSource<Stringapply(String s) throws Throwable {
                        System.out.println("flatMap"+s);
                        return Observable.just("1064902354") ;
                    }
                })
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        System.out.println("onSubscribe:");
                    }       

流程分析

           //起点 (Observable)
Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<String> emitter) {
        emitter.onNext("测试");
    }
})
        .subscribe(
                //终点 (Observer)
                new Observer<String>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                System.out.println("onSubscribe:");
            }

            @Override
            public void onNext(@NonNull String integer) {
                System.out.println("onNext:" + integer);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                System.out.println("onError:" + e.toString());
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        });

Observable当做起点,将 Observer 当做终点,以最简洁的使用方式为背景,我们来分析一下 RxJava最基础的工作流程。

我们先看create

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

RxJavaPlugins.onAssembly 是每个操作符都会涉及到的一个流程,这里是Rxjava留给用户的一个Hook点,可以通过设置 onObservableAssembly ,可以对每个操作符进行hook监听。

在create中,以我们自定义的source 为参数 进行了 ObservableCreate 的创建。稍后我们会对ObservableCreate 源码进行分析。

接下来看看终点

public interface Observer<@NonNull T> {
    void onSubscribe(@NonNull Disposable d);
    void onNext(@NonNull T t);
    void onError(@NonNull Throwable e);
    void onComplete();
}

只是一个接口,提供了四个方法。

起点和终点搞清楚了,我们接下来看下订阅方法。

public final void subscribe(@NonNull Observer<? super T> observer) {
    Objects.requireNonNull(observer, "observer is null");
    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);
        Objects.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
        //最终调用的是这里
        subscribeActual(observer);
    } catch (NullPointerException e) { // NOPMD
        throw e;
    } catch (Throwable e) {
        Exceptions.throwIfFatal(e);
        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(@NonNull Observer<? super T> observer);

这是一个抽象方法,所以实际调用的方法应该在子类中。这里就是由create的创建的ObservableCreate

@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<>(observer);
    observer.onSubscribe(parent);
    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}

这里首先将observer 进行一层封装,封装成发射器 CreateEmitter ,然后调用的 observer 的 onSubscribe 方法,这就是为什么我们每次进行订阅的时候首先会回调 onSubscribe。

这个方法里面的source 就是我们我们在起点 调用create 方法时 传入的ObservableOnSubscribe

    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<String> emitter) {
            emitter.onNext("测试");
        }
     })
------------------------------------------------------------------------------      
    final ObservableOnSubscribe<Tsource;
    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }      

然后source 调用subscribe(parent) 方法,将发射器 CreateEmitter 会调到我们的接口中。

在起点的 subscribe 方法中 ,通过调用发射器的 onNext 方法 进行数据发送,我们看下 emitter.onNext() 做了一些什么事情。

final Observer<? super T> observer;

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

@Override
public void onNext(T t) {
    if (t == null) {
        onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
        return;
    }
    if (!isDisposed()) {
        observer.onNext(t);
    }
}

在这里是对数据进行判断,如果数据正常,调用observer的onNext方法,也就是终点的onNext的方法。如果有异常会执行onError.

这样我们最基本的流程就可以串起来了。

image-20220616155852536

接下来,我们再分析一个map 操作符

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
        emitter.onNext("测试1");
    }
})
        .map(new Function<StringString>() {
            @Override
            public String apply(String s) throws Throwable {
                return "测试1";
            }
        })
        .subscribe(...)

我们来看源码

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

相同的配方,相同的味道,这里也是进行了一层封装,但是这里封装了两个东西,一个是this,一个是我们传入的接口。然后将封装的包裹进行返回。

那this 是什么呢?this就是整个上游,也就是通过create创建的ObservableCreate

接下来我们看订阅 subscribe(...) ,它是由map操作符返回的 Observable 执行的。我们来详细看下内部方法。

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

这里是对我们的终点(观察者) 和我们在map操作符中自定义的Function 进行了一个封装。

这里的source 就是前面提到的this。

source 通过调用 subscribe 方法 ,就会走到 ObservableCreate 的 subscribeActual 方法中。

protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<>(observer);
    observer.onSubscribe(parent);
    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}

后续的就跟上文的流程一样了:

对 MapObserver 进行再次封装,封装成 CreateEmitter

->先调用 观察者的 onSubscribe

->然后调用source ( ObservableOnSubscribe ) 的 subscribe 方法 ,到我们自定义的ObservableOnSubscribe 接口的方法中

->然后 发射器 CreateEmitter 调用 onNext 进行数据传输

在上文讲到这个步骤 调用的onNext 的方法是 我们自定义的观察者的onNext方法,但是这里调用的onNext方法是 MapObserver 中的onNext 方法,因为 CreateEmitter 是对 MapObserver 的二次封装。

static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
    final Function<? super T, ? extends U> mapper;
    //downstream == actual
    MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
        super(actual);
        this.mapper = mapper;
    }
    
    @Override
    public void onNext(T t) {
       ...............
        U v;
        try {
            v = Objects.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
        } catch (Throwable ex) {
        ...............  
        }
        downstream.onNext(v);
    }

在 MapObserver 的onNext方法中,将上游传入的参数经过mapper.apply 方法,也就是我们在map操作符中自定义的Function,进行数据转换并返回转换后的数据

//这个Function == mapper
map(new Function<ObjectObject>() {
    @Override
    public Object apply(Object o) throws Throwable {
        return o;
    }
})

最后我们由 downstream 再将转换后的数据分发下去。这里的 downstream 就是我们的终点观察者了。

最终的流程大概就是这个样子

image-20220616224546729

写在最后

RxJava工作流程的分析就暂时先到这里了,希望能对大家有所帮助,如果有更好的见解,欢迎留言讨论。