目录
一、Is what 是什么
二、Concept 概念
三、Basic realization 基本实现
四、Scheduler 线程控制(上)
五、Scheduler 线程控制(下)
六、变换
因个人学习需要,故文章内容均为网上摘抄整理,感谢创作者的辛勤,源文章地址请看文末。
Scheduler 的作用
Scheduler
调度器:相当于线程控制器,用来指定每一段代码运行在什么线程。
注意:在不指定线程的情况下,
RxJava
遵循线程不变的原则,即:在哪个线程调用subscribe()
,就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。
RxJava 内置的 Scheduler
-
Schedulers.immediate()
在当前线程运行,相当于不指定线程。是默认的Scheduler
。 -
Schedulers.newThread()
启用新线程,并在新线程执行操作。 -
Schedulers.io()
I/O
操作(读写文件、数据库,网络信息交互等)使用。
内部使用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下io()
比newThread()
更有效率。
不要把计算工作放在
io()
中,避免创建不必要的线程。
-
Schedulers.computation()
计算使用。
计算指CPU
密集型计算,即不会被I/O
等操作限制性能的操作,如图形计算。内部使用固定的线程池,大小为CPU
核数。
不要把
I/O
操作放在computation()
中,否则I/O
操作的等待时间会浪费CPU
。
-
AndroidSchedulers.mainThread()
指定操作在主线程运行(Android
专用)。
使用
-
subscribeOn()
指定subscribe()
所发生的线程,即Observable.OnSubscribe
被激活时所处的线程。或叫事件产生的线程。 -
observeOn()
指定Subscriber
所运行在的线程。或叫事件消费的线程。
// 示例
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) //指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) //指定Subscriber的回调发生在主线程
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer number) {
Log.d(tag, "number:" + number);
}
});
示例解释:
由于 subscribeOn(Schedulers.io())
的指定,被创建的事件的内容1、2、3、4 将会在 IO
线程发出;
由于observeOn(AndroidScheculers.mainThread())
的指定,subscriber
数字的打印将发生在主线程 。
这种在 subscribe()
之前加入 subscribeOn(Scheduler.io())
和 observeOn(AndroidSchedulers.mainThread())
的方式适用于多数 『后台线程取数据,主线程显示』的程序策略。
//示例:加载图片
int drawableRes = ...;
ImageView imageView = ...;
Observable.create(new OnSubscribe<Drawable>() {
@Override
public void call(Subscriber<? super Drawable> subscriber) {
Drawable drawable = getTheme().getDrawable(drawableRes));
subscriber.onNext(drawable);
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(new Observer<Drawable>() {
@Override
public void onNext(Drawable drawable) {
imageView.setImageDrawable(drawable);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(activity, "Error!",
Toast.LENGTH_SHORT).show();
}
});
示例解释:
call()
回调中加载图片发生在 IO
线程,而设置图片发在主线程。