参考自:
- http://www.jianshu.com/p/464fa025229e (强烈推荐,连载!!!)
- http://blog.csdn.net/jdsjlzx/article/details/51685769
1.Disposable
这个单词的字面意思是一次性用品,用完即可丢弃的. 那么在RxJava中怎么去理解它呢, 对应于上面的水管的例子, 我们可以把它理解成两根管道之间的一个机关, 当调用它的dispose()方法时, 它就会将两根管道切断,从而导致下游收不到事件.
注意:调用dispose()并不会导致上游不再继续发送事件, 上游会继续发送剩余的事件,但下游不会再接收事件onComplete和onError都不会走了。
那怎么才能在dispose()之后上游也不发送事件了呢?
调用dispose()方法时就会切断水管, 使得下游收不到事件, 既然收不到事件, 那么也就不会再去更新UI了. 因此我们可以在Activity中将这个Disposable 保存起来, 当Activity退出时, 切断它即可;使用MVP的话,在onDestroy里调用presenter/model里的方法切断。
那如果有多个Disposable 该怎么办呢, RxJava中已经内置了一个容器CompositeDisposable, 每当我们得到一个Disposable时就调用CompositeDisposable.add()将它添加到容器中, 在退出的时候, 调用CompositeDisposable.clear() 即可切断所有的水管.
Observable.just("Kobe", "Curry")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
JustActivity.this.d = d;
txt.append("onSubscribe d.isDisposed " + d.isDisposed() + "\n");
}
@Override
public void onNext(String s) {
txt.append("onNext " + s + "\n");
d.dispose();
txt.append("onNext d.isDisposed " + d.isDisposed() + "\n");
}
@Override
public void onError(Throwable e) {
txt.append("onError" + e.getMessage() + "\n");
}
@Override
public void onComplete() {
txt.append("onComplete" + "\n");
}
});
输出的结果是:
onSubscribe d.isDisposed false
onNext Kobe
onNext d.isDisposed true
2.ObservableEmitter
Emitter是发射器的意思,那就很好猜了,这个就是用来发出事件的,它可以发出三种类型的事件,通过调用emitter的onNext(T value)、onComplete()和onError(Throwable error)就可以分别发出next事件、complete事件和error事件。
但是,请注意,并不意味着你可以随意乱七八糟发射事件,需要满足一定的规则:
上游可以发送无限个onNext, 下游也可以接收无限个onNext.
当上游发送了一个onComplete后, 上游onComplete之后的事件将会继续发送, 而下游收到onComplete事件之后将不再继续接收事件.
当上游发送了一个onError后, 上游onError之后的事件将继续发送, 而下游收到onError事件之后将不再继续接收事件.
上游可以不发送onComplete或onError.
最为关键的是onComplete和onError必须唯一并且互斥, 即不能发多个onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError, 反之亦然
注意:关于onComplete和onError唯一并且互斥这一点, 是需要自行在代码中进行控制, 如果你的代码逻辑中违背了这个规则, 并不一定会导致程序崩溃. 比如发送多个onComplete是可以正常运行的, 依然是收到第一个onComplete就不再接收了, 但若是发送多个onError, 则收到第二个onError事件会导致程序会崩溃.
Observable.create(new ObservableOnSubscribe<FirstType>() {
@Override
public void subscribe(ObservableEmitter<FirstType> e) throws Exception {
Log.d("test", "subscribe " + e.isDisposed());
//运行在后台线程,子线程不能动态更新UI,这行代码会出错
//txt.append("subscribe " + e.isDisposed() + "\n");
if (!e.isDisposed()) {
e.onNext(new FirstType("James"));
e.onNext(new FirstType("Durant"));
e.onComplete();
}
}
})
//在后台线程上运行 主要改变的是订阅的线程,subscribe()执行的线程
.subscribeOn(Schedulers.io())
//在主线程上通知 主要改变的是发送的线程,onNext()执行的线程
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<FirstType, SecondType>() {
@Override
public SecondType apply(@NonNull FirstType firstType) throws Exception {
return new SecondType(firstType.FirstName);
}
})
.subscribe(new Observer<SecondType>() {
@Override
public void onSubscribe(Disposable d) {
txt.append("onSubscribe " + d.isDisposed() + "\n");
Log.d("test", "onSubscribe d.isDisposed() " + d.isDisposed());
}
@Override
public void onNext(SecondType secondType) {
txt.append("onNext " + secondType.secondName + "\n");
Log.d("test", "onNext " + secondType.secondName);
}
@Override
public void onError(Throwable e) {
txt.append("onError" + "\n");
Log.d("test", "onError " + e.getMessage());
}
@Override
public void onComplete() {
txt.append("onComplete" + "\n");
Log.d("test", "onComplete ");
}
});
运行结果:
//可见onSubscribe方法最先被调用
onSubscribe d.isDisposed() false
subscribe false
onNext James
onNext Durant
onComplete
3.在RxJava中, 已经内置了很多线程选项供我们选择
例如有
- Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
- Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
- Schedulers.newThread() 代表一个常规的新线程
- AndroidSchedulers.mainThread() 代表Android的主线程
这些内置的Scheduler已经足够满足我们开发的需求, 因此我们应该使用内置的这些选项, 在RxJava内部使用的是线程池来维护这些线程, 所以效率也比较高.
4.每十秒请求一次数据
/*
* interval的三个参数
* long period, TimeUnit unit, Scheduler scheduler
* period 在发射第一个值之前等待的初始延迟时间
* unit 间隔大小
* scheduler 时间单位
*/
Observable.interval(0, 10, TimeUnit.SECONDS)
.flatMap(new Function<Long, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(Long aLong) throws Exception {
return null;//这里放网络请求
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
}
});