从接触了解学习使用Rxjava1.0 到Rxjava2.0有一年多了吧, 貌似,没有留下来过什么,一篇博客,日记都没有写过.主要是网上的资源太多了,都是重复的.再加上人比较懒,所以..... 所有今天以后.陆续,写点Rxjava2.0的笔记,方便以后查看.先从最基本的使用开始吧,(只记使用方法,不写原理分析).
一.添加依赖
//RxJava的依赖包(我使用的最新版本) compile 'io.reactivex.rxjava2:rxjava:2.1.1' //RxAndroid的依赖包 compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
二.基本用法
//创建被观察者 Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception { log("我是被观察者--subscribe---" + getT()); //通知观察者 e.onNext("通知观察者"); e.onComplete(); } }); //创建观察者 Observer observer = new Observer<String>() { @Override public void onSubscribe(@NonNull Disposable d) { log("onSubscribe--" + getT()); } @Override public void onNext(@NonNull String s) { log("onNext--" + getT() + "---" + s); } @Override public void onError(@NonNull Throwable e) { log("onError--" + getT()); } @Override public void onComplete() { log("onComplete--" + getT()); } }; observable.subscribeOn(Schedulers.io()) .subscribe(observer);打印日志如下
onSubscribe--main 我是被观察者--subscribe---main onNext--main---通知观察者 onComplete--main
三.线程切换
在RxJava 中,Scheduler,相当于线程控制器,RxJava 通过它来指定每一段代码应该运行在什么样的线程。RxJava 已经内置了几个 Scheduler ,它们已经适合大多数的使用场景。
Scheduler 的 API
1.Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
2.Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
3.Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
4.Schedulers.computation(): **计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
5.Android 还有一个专用的** AndroidSchedulers.mainThread()**,它指定的操作将在 Android 主线程运行。
有了这几个 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。 subscribeOn() : 指定Observable(被观察者)所在的线程,或者叫做事件产生的线程。 observeOn() : 指定 Observer(观察者)所运行在的线程,或者叫做事件消费的线程。
Scheduler 的 API
1.Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
2.Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
3.Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
4.Schedulers.computation(): **计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
5.Android 还有一个专用的** AndroidSchedulers.mainThread()**,它指定的操作将在 Android 主线程运行。
有了这几个 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。 subscribeOn() : 指定Observable(被观察者)所在的线程,或者叫做事件产生的线程。 observeOn() : 指定 Observer(观察者)所运行在的线程,或者叫做事件消费的线程。
例子:
observable.subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(observer);
日志:
onSubscribe--main 我是被观察者--subscribe---RxNewThreadScheduler-1 onNext--main---通知观察者 onComplete--main
注:
多次指定上游的线程只有第一次指定的有效, 也就是说多次调用subscribeOn() 只有第一次的有效, 其余的会被忽略.
多次指定下游的线程是可以的, 也就是说每调用一次observeOn() , 下游的线程就会切换一次.
多次指定下游的线程是可以的, 也就是说每调用一次observeOn() , 下游的线程就会切换一次.
例子:
observable.subscribeOn(Schedulers.newThread()) .subscribeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread()) .observeOn(Schedulers.newThread()) .subscribe(observer);
日志:
E/MainActivity: onSubscribe--main E/MainActivity: 我是被观察者--subscribe---RxNewThreadScheduler-1 E/MainActivity: onNext--RxNewThreadScheduler-2---通知观察者 E/MainActivity: onComplete--RxNewThreadScheduler-2可以看到, 上游虽然指定了两次线程, 但只有第一次指定的有效, 依然是在RxNewThreadScheduler-1线程中, 而下游则跑到了RxNewThreadScheduler-2中.
以上为线程调度操作.可以在此基础上尽情的进行异步操作。
四.doOnSubscribe和doFinally操作符
在这里,之所以,说这两个操作符,是因为.这两个操作符,有用,方便.使用他们可以是代码更加的简洁明了...
这两个操作符的作用.
1.doOnSubscribe: 与 Observer.onSubscribe() 方法作用一样.都是在数据源发送前执行. 区别在于doOnSubscribe可以制定线程,doOnSubscribe运行在subscribe()发生的线程,假设在doOnSubscribe()之后有subscribeOn()的话,它讲运行在它之后的最近的subscribeOn()所指定的线程中.Observer.onSubscribe()执行在数据源发射时所在的线程,注:而非:subscribeOn(),observeOn()所指定的线程.
例子:
observable.subscribeOn(Schedulers.newThread()) .subscribeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread()) .observeOn(Schedulers.newThread()) .doFinally(new Action() { @Override public void run() throws Exception { log("doFinally--" + getT()); observable1 .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<String>() { @Override public void onSubscribe(@NonNull Disposable d) { log("onSubscribe**--" + getT()); } @Override public void onNext(@NonNull String s) { log("onNext**--" + getT()); } @Override public void onError(@NonNull Throwable e) { log("onError**--" + getT()); } @Override public void onComplete() { log("onComplete**--" + getT()); } }); } }) .subscribe(observer);
日志:
E/MainActivity: onSubscribe--main E/MainActivity: 我是被观察者--subscribe---RxNewThreadScheduler-1 E/MainActivity: onNext--RxNewThreadScheduler-2---通知观察者 E/MainActivity: onComplete--RxNewThreadScheduler-2 E/MainActivity: doFinally--RxNewThreadScheduler-2 E/MainActivity: onSubscribe**--RxNewThreadScheduler-2 E/MainActivity: 我是被观察者--subscribe---RxNewThreadScheduler-2 E/MainActivity: onNext**--main E/MainActivity: onComplete**--main
如上在doFinally中发射在事件.在RxNewThreadScheduler-2线程中订阅observable1被观察者. 而observable1的onSubscribe()执行在
observable1订阅所在的线程即RxNewThreadScheduler-2线程,与
subscribeOn
和
observeOn
无关.
doOnSubscribe使用场景: 修改源, 在数据源发射之前,做一些操作,比如: Rxjava2.0 与 Retrofit2.0 使用时,在doOnSubscribe中做 网络是否链接判断, 亦或者 显示加载框进度框.
小结:
1).如上所述,某些时候,我们需要在doOnSubscribe中做一些ui操作.那么ui的操作需要在主线程中,我们只需要在doOnSubscribe()后调用subscribe(),即可完成线程切换.若后面有多个subscribe(),则doOnSubscribe()的线程只与离他最近的subscribe(),有关.
2).若doOnSubscribe()前后都没有调用subscribe()方法,那么doOnSubscribe()运行在subscribe()发生的线程(或者说是数据源发射的线程).doOnSubscribe()线程与observerOn制定的线程无关.
3).doOnSubscribe()线程与subscribe().有关,切只与在doOnSubscribe()之后的subscribe()有关.
2.doFinally():根据名称就能知道该方法是干什么的.及在onCompleted和或onError后调用的方法.
doFinally()使用场景: 订阅即将执行完成前,想要做的操作.比如: 关闭网络加载进度框.
本篇博客到此位置, 待续未完,下一篇继续, 末尾附上联系的demo.