RxJava2实现线程切换

闲谈RxJava

  • RxJava:"a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)
  • 异步。它其实就是一个实现异步操作的库,基于观察者模式,而且是链式调用的。

RxJava的三个基本元素

被观察者(Observable)、观察者(Observer)、订阅(subscribe)。

1、创建被观察者:
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(0);
        e.onNext(1);
        e.onNext(2);
        e.onComplete();
    }
});
2、创建观察者:
Observer observer = new Observer() {

        @Override
        public void onSubscribe(Disposable d) {}

        @Override
        public void onNext(Integer o) {}

        @Override
        public void onError(Throwable e) {}

        @Override
        public void onComplete() {}
    };
3、建立订阅关系:
observable.subscribe(observer);

  • 被观察者的创建常用三种:

    Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
                emitter.onNext(0);
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onComplete();
            });
    Observable.just(0);
    Observable.fromIterable(Arrays.asList(0,1, 2));

  • 观察者的创建有两种:

    Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {}

            @Override
            public void onNext(Integer o) {}

            @Override
            public void onError(Throwable e) {}

            @Override
            public void onComplete() {}
        };
    Consumer<Integer> consumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {}
        };

  • 订阅关系有四种:

Disposable subscribe();
void subscribe(Observer<? super T> observer);
Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,Action onComplete, Consumer<? super Disposable> onSubscribe);
<E extends Observer<? super T>> E subscribeWith(E observer);

调度器Scheduler

  • Schedulers.computation():代表CPU计算密集型的操作, 例如需要大量计算的操作。
  • Schedulers.newThread():直接开启一个新的线程。
  • Schedulers.io():开启一个io线程,完成对网络请求和文件读写数据库增删改查等操作。那io和newThread有什么区别呐?newThread不管有没有线程,他都会去重新开启一个新的线程来进行操作,并且没线程池维护。但是io的线程是无上限的,并且最大的一个好处是它会去重用空闲的线程,而不是每次都开启一个线程来使用,效率上比newThread要高。所以,一般我们在使用的时候是直接使用io这个方法。
  • AndroidSchedulers.mainThread():android一个专门的线程,用来指定操作在主线程完成。

RxJava实现线程切换

subscribeOn():指定Observable被观察者在哪个线程执行。要注意的是,如果多次调用此方法,只有第一次有效。
observeOn():指定Observe观察者在哪个线程中执行。多次指定观察者接收线程是可以的,每调用一次observerOn(),下游的线程就会切换一次。

  • 代码探索:

    Observable.just(0)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",当前线程mainThread = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.io())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",当前线程io = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.newThread())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",当前线程newThread = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.computation())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",当前线程computation = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(Schedulers.single())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",当前线程single = " + Thread.currentThread().getName());
            return ++integer;
        })
        .observeOn(AndroidSchedulers.mainThread())
        .map(integer -> {
            Log.i(TAG, "integer=" + integer + ",当前线程mainThread = " + Thread.currentThread().getName());
            return ++integer;
        })
        .subscribe();

  • log日志:

    MyAppUtils: integer=0,当前线程mainThread = main
    MyAppUtils: integer=1,当前线程io = RxCachedThreadScheduler-3
    MyAppUtils: integer=2,当前线程newThread = RxNewThreadScheduler-1
    MyAppUtils: integer=3,当前线程computation = RxComputationThreadPool-1
    MyAppUtils: integer=4,当前线程single = RxSingleScheduler-1
    MyAppUtils: integer=5,当前线程mainThread = main

Subject

  • AsyncSubject:无论输入多少参数、什么时候订阅、是否Completed,永远只输出最后一个参数;
  • BehaviorSubject:发送离订阅最近的上一个值,没有上一个值的时候会发送默认值;
  • PublishSubject:最正常的Subject,从那里订阅就从那里开始发送数据;
  • ReplaySubject:无论何时订阅,都会将所有历史订阅内容全部发出。
发布了55 篇原创文章 · 获赞 61 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Agg_bin/article/details/93630390