RxJava学习笔记

本文详细介绍了为何使用RxJava,其基于观察者模式的工作原理,如何通过subscribeOn()和observeOn()进行线程分配,以及flatmap用于处理嵌套请求。此外,还讲解了doOnNext和dispose销毁的概念,以及RxJava中的Hook点和操作符的应用。

为什么要使用RxJava

Rx的思维,是响应式编程的思维,从起点到终点不断的链式调用,使用RxJava可以改变思维方式,提升效率。

  • RxJava基于观察者设计模式,三个要素:
    被观察者(起点)Observable,订阅 subscribe,观察者(终点)Observer。
  • 数据从起点流向终点,中间可以做过滤,也是卡片式编程,加入各种操作符,如map、flatmap、zip、concat等。下游只找上游的类型。
    例如想通过输入一个String字符串,最终转换成一个Bitmap,可以通过内部的操作符添加转换的规则,流入是一个String,流出Bitmap。
    在这里插入图片描述

分配线程

subscribeOn 给上面代码分配线程
如:subscribeOn(Schedulers.io())
observeOn 给下面代码分配线程
如:observeOn(AndroidSchedulers.mainThread())

flatmap解决嵌套请求

给一个数据,分成多个数据
在这里插入图片描述
onNext(1);----->
        flatmap(1–>发送3次 1 + “AAA”)----->
                subscribe{“1+AAA”,“1+AAA”,“1+AAA”}

Observable
                .create(new ObservableOnSubscribe<ProgramBean>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<ProgramBean> emitter) throws Throwable {
                        ProgramBean bean = getData();
                        emitter.onNext(bean);
                    }
                })
                .subscribeOn(Schedulers.io())
                .flatMap(new Function<ProgramBean, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(ProgramBean bean) throws Throwable {
                        // 返回一个迭代器,会控制发射多次
                        return Observable.fromIterable(bean.list);
                    }
                })
                .flatMap(new Function<String, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(String s) throws Throwable {
                        return null;
                    }
                }).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {

                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull String o) {

                    }

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

                    }

                    @Override
                    public void onComplete() {

                    }
                });

doOnNext

当使用subscribe后,链式调用就到了终点,没有返回值可以再次进行处理了,doOnNext返回Observable,可以继续进行链式调用。常应用于 异步->UI->异步->UI->异步->UI 切换的场景。

dispose销毁

在订阅时声明到外面,在页面onDestroy时及时销毁。

设计模式

  • RxJava是基于观察模式的改装
  • 标准的观察者模式是有一个被观察者,多个观察者,被观察者发生改变,观察者触发改变
  • RxJava是有多个被观察者,一个观察者,耦合度更低,也叫发布订阅模式
  • Observer 观察者,就是一个接口,由用户来实现,传入的泛型T由onNext返回
public interface Observer<@NonNull T> {
    void onSubscribe(@NonNull Disposable d);
    void onNext(@NonNull T t);
    void onError(@NonNull Throwable e);
    void onComplete();
}
  • Observable 被观察者,包含了create方法,创建一个Observalble,也定义了所有的操作符,create方法,需要用户传入一个ObservableOnSubscribe,创建一个ObservableCreate,在ObservableCreate中保存为一个成员变量,create方法会返回一个ObservableCreate对象,返回这个对象才可以继续进行链式调用,其他所有的操作符也是同理
    @CheckReturnValue
    @NonNull
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <@NonNull T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
        Objects.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
    }
	public final class ObservableCreate<T> extends Observable<T> {
	    final ObservableOnSubscribe<T> source;
	    public ObservableCreate(ObservableOnSubscribe<T> source) {
	        this.source = source;
	    }
	    ...
    }
  • subscribe 订阅,subscribe是在ObservableSource接口中定义的方法,实现是在Observalble中,用户需要传入一个自定义的Observer,最后调用了subscribeActual(observer)方法,
@FunctionalInterface
public interface ObservableSource<@NonNull T> {

    /**
     * Subscribes the given {@link Observer} to this {@link ObservableSource} instance.
     * @param observer the {@code Observer}, not {@code null}
     * @throws NullPointerException if {@code observer} is {@code null}
     */
    void subscribe(@NonNull Observer<? super T> observer);
}
    @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    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);
            // 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是一个抽象方法,实现是在ObservableCreate中,在ObservableCreate的subscribeActual实现中,创建一个发射器,传入observer,调用onSubscribe,这也是只要一订阅,马上就会执行subscribe回调的原因。
最后执行source.subscribe(parent); soure就是前面创建被观察者时用户传入的ObservableOnSubscribe,parent就是发射器,调用发射器的onNext,因为创建发射器时,保存了observer,这样就会调用到Observer的onNext,再回调给用户。

    @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);
        }
    }
public interface Emitter<@NonNull T> {
    void onNext(@NonNull T value);
    void onError(@NonNull Throwable error);
    void onComplete();
}
	//发射器创建
		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);
            }
        }

RxJava Hook点

可以看到,Rxjava每个操作符对应都会创建一个Observablexxx,在创建这个对象之后,都会传入到RxJavaPlugins.onAssembly()中,RxJavaPlugins.onAssembly()静态方法作为了整个RxJava操作符的拦截
在这里插入图片描述

    public static <@NonNull 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只有setOnObservableAssembly()方法赋值

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

此方法RxJava中并未赋值,所以onAssembly中不会调用到apply()方法,只有当用户调用了setOnObservableAssembly方法时,才会调用apply(),这也是RxJava提供给用户的全局监听的方法,这里不能返回null,需要返回Observable,保证链式调用可以继续

        RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
            @Override
            public Observable apply(Observable observable) throws Throwable {
                return observable;
            }
        });

操作符

为了保证链式调用流程不断,RxJava采用洋葱模型,通过封包裹,拆包裹的方式,把每个操作符一层层打包,以map为例,源码如图
在这里插入图片描述
在调用map操作符时,传入一个Function,在调用subscribe时,会调到ObservableMap的subscribeActual方法,在方法中,包裹了一层MapObserver,又把MapObserver传入到了ObservableCreate中,再包裹一层发射器,将发射器通过参数传给用户

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

用户就可以使用发射器,调用onNext,进行拆包裹,一层一层递进地调用onNext(),最后达到“终点”,也就是用户自己实现的onNext

//用户
   Observable
                .create(new ObservableOnSubscribe<ProgramBean>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<ProgramBean> emitter) throws Throwable {
                        ProgramBean bean = getData();
                        emitter.onNext(bean);
                    }
                })
//CreateEmitter发射器
        @Override
        public void onNext(T t) {
            if (t == null) {
                onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
                return;
            }
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }
//MapObserver
        @Override
        public void onNext(T t) {
            if (done) {
                return;
            }

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

            U v;

            try {
                v = Objects.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            downstream.onNext(v);
        }
			.subscribe(new Observer<String>() {

                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull String o) {

                    }

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

                    }

                    @Override
                    public void onComplete() {

                    }
                });

在MapObserver中调用mapper.apply(t),把变换的逻辑再交给用户,就完成了整体的流程。

线程切换原理

subscribeOn()

  • 给上面的代码分配线程,常用
subscribeOn(Schedulers.io())
  • 首先看Schedulers.io()是怎么做的
    Schedulers.io()方法直接返回了一个IO对象,IO在静态代码块中赋值
    @NonNull
    public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }
    
    static {
        SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());

        COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());

        IO = RxJavaPlugins.initIoScheduler(new IOTask());

        TRAMPOLINE = TrampolineScheduler.instance();

        NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
    }

可以看到,不仅是IO,还有很多不同的策略。IO实例化时,创建了一个IOTask(),IOTask()的get()方法,返回一个IoScheduler(),在IoScheduler的构造方法中,可以看到创建了线程池。也就是说,Schedulers.io()实际上就是创建了线程池

    static final class IOTask implements Supplier<Scheduler> {
        @Override
        public Scheduler get() {
            return IoHolder.DEFAULT;
        }
    }

    static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler();
    }

    public IoScheduler(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.pool = new AtomicReference<>(NONE);
        start();
    }

    @Override
    public void start() {
        CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
        if (!pool.compareAndSet(NONE, update)) {
            update.shutdown();
        }
    }
  • SubscribeOn(),通过上面的分析,这里实际上是把IoScheduler作为参数传递进去了,创建Observable子类ObservableSubscribeOn来保存一份IoScheduler,同时也给父类声明的source赋值了,这个source实际上是用户上一步调用返回的Observable,在SubscribeTask的run方法中使用。在执行subscribe订阅后,会调用到subscribeActual方法
    public final Observable<T> subscribeOn(@NonNull Scheduler scheduler) {
        Objects.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<>(this, scheduler));
    }
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> observer) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<>(observer);

        observer.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }
	....
}

SubscribeTask是一个Runnable,最终会把它交给线程池来运行,run方法中使用了前面保存的source,这也是可以做到给上面的代码分配线程的效果
scheduleDirect中会创建一个Worker对象,调用worker.schedule(),最终调用IoScheduler的schedule方法,最后在scheduleActual方法中,调用线程池的submit或schedule方法

    @NonNull
    public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
        Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);

        if (parent != null) {
            if (!parent.add(sr)) {
                return sr;
            }
        }

        Future<?> f;
        try {
            if (delayTime <= 0) {
                f = executor.submit((Callable<Object>)sr);
            } else {
                f = executor.schedule((Callable<Object>)sr, delayTime, unit);
            }
            sr.setFuture(f);
        } catch (RejectedExecutionException ex) {
            if (parent != null) {
                parent.remove(sr);
            }
            RxJavaPlugins.onError(ex);
        }

        return sr;
    }

ObserveOn()

  • 给下面的代码分配线程,常用
observeOn(AndroidSchedulers.mainThread())
  • AndroidSchedulers.mainThread()属于RxAndroid库中的内容,想要使用,必须导入RxAndroid库。
  • 切换到主线程,使用的是Android的Handler机制。AndroidSchedulers.mainThread() 主要作用就是拿主线程的handler,保存在HandlerScheduler的成员变量中
    private static final class MainHolder {
        static final Scheduler DEFAULT = internalFrom(Looper.getMainLooper(), true);
    }
	final class HandlerScheduler extends Scheduler {
	    private final Handler handler;
	    private final boolean async;
	
	    HandlerScheduler(Handler handler, boolean async) {
	        this.handler = handler;
	        this.async = async;
	    }
	    ...
	}
  • ObserveOn()
    创建了ObservableObserveOn,传入了主线程handler的scheduler,在中也同样的,保存了一份主线程的scheduler
    public final Observable<T> observeOn(@NonNull Scheduler scheduler, boolean delayError, int bufferSize) {
        Objects.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn<>(this, scheduler, delayError, bufferSize));
    }
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;
    }
    ...
}

在subscribeActual方法中,首先判断是不是当前执行的线程,如果不是,再切换线程

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

切换线程时,首先调用主线程scheduler的createWorder方法创建worker,返回到HandlerWorker中,可以看到

    @Override
    public Worker createWorker() {
        return new HandlerWorker(handler, async);
    }

创建一个ObserveOnObserver,在调用onSubscribe或onNext等时,会调用它的schedule()方法

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

最终调用到主线程scheduler的worker的schedule方法在执行worker.schedule时,执行了,handler.sendMessage

 @Override
        @SuppressLint("NewApi") // Async will only be true when the API is available to call.
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            if (run == null) throw new NullPointerException("run == null");
            if (unit == null) throw new NullPointerException("unit == null");

            if (disposed) {
                return Disposable.disposed();
            }

            run = RxJavaPlugins.onSchedule(run);

            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);

            Message message = Message.obtain(handler, scheduled);
            message.obj = this; // Used as token for batch disposal of this worker's runnables.

            if (async) {
                message.setAsynchronous(true);
            }

            handler.sendMessageDelayed(message, unit.toMillis(delay));

            // Re-check disposed state for removing in case we were racing a call to dispose().
            if (disposed) {
                handler.removeCallbacks(scheduled);
                return Disposable.disposed();
            }

            return scheduled;
        }

worker.schedule(this);方法中,传递的参数this为Runnable,ObserveOnObserver实现的Runnable接口,run方法也在ObserveOnObserver中可以找到,当handler切换到主线程后,执行run方法,run方法执行在主线程,最终调用了用户实现的observer.onNext等方法。

        @Override
        public void run() {
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值