原文链接
基础
核心 : Observables(被观察者,事件源)和 Observer(观察者), Subject 是同时继承了 Observable 和 Observer。
Subscriber 是 Observer 的一个实现。
interface Observer<T> {
void onCompleted();
void onError(java.lang.Throwable e);
void onNext(T t);
}
Observable.just() 是用来创建只发出一个事件就结束的Observable对象
变换
map操作符
用来把把一个事件转换为另一个事件.
两点:
1.Observable和Subscriber可以做任何事情
Observable可以是一个数据库查询,Subscriber用来显示查询结果;Observable可以是屏幕上的点击事件,Subscriber用来响应点击事件;Observable可以是一个网络请求,Subscriber用来显示请求结果。2.Observable和Subscriber是独立于中间的变换过程的。
在Observable和Subscriber中间可以增减任何数量的map。整个系统是高度可组合的,操作数据是一个很简单的过程。
每一个Observerable对象在终结的时候都会调用onCompleted()或者onError()方法.
这种模式有以下几个优点:
1.只要有异常发生onError()一定会被调用
这极大的简化了错误处理。只需要在一个地方处理错误即可以。
2.操作符不需要处理异常
将异常处理交给订阅者来做,Observerable的操作符调用链中一旦有一个抛出了异常,就会直接执行onError()方法。
3.你能够知道什么时候订阅者已经接收了全部的数据。
使用RxJava,Observable对象根本不需要知道如何处理错误!操作符也不需要处理错误状态-一旦发生错误,就会跳过当前和后续的操作符。所有的错误处理都交给订阅者来做。
Observable.from()方法,它接收一个集合作为输入,然后每次输出一个元素给subscriber:
Observable.from("url1", "url2", "url3")
.subscribe(url -> System.out.println(url));
flatMap()
Observable.flatMap()接收一个Observable的输出作为输入,同时输出另外一个Observable。直接看代码:
Observable.just(list)
.flatMap(new Func1<List<String>, Observable<String>>() {
@Override
public Observable<String> call(List<String> strings) {
return Observable.from(list);
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("MainActivity", s);
}
});
filter()
输出和输入相同的元素,并且会过滤掉那些不满足检查条件的。
take()
输出最多指定数量的结果。
doOnNext()
doOnNext()允许我们在每次输出一个元素之前做一些额外的事情,比如这里的保存标题。
query("Hello, world!")
.flatMap(urls -> Observable.from(urls))
.flatMap(url -> getTitle(url))
.filter(title -> title != null)
.take(5)
.doOnNext(title -> saveTitle(title))
.subscribe(title -> System.out.println(title));
zip()
可以很简单的将多个REST请求结合起来。比如我们有一个请求是获取照片的,还有一个请求是获取元数据的,我们就可以将这两个请求并发的发出,并且等待两个结果都返回之后再做处理:
Observable.zip(
service.getUserPhoto(id),
service.getPhotoMetadata(id),
(photo, metadata) -> createPhotoWithData(photo, metadata))
.subscribe(photoWithData -> showPhoto(photoWithData));
普通代码转换成 Observable
绝大多数时候Observable.just() 和 Observable.from() 能够帮助你从遗留代码中创建 Observable 对象
private Object oldMethod() { ... }
public Observable<Object> newMethod() {
return Observable.just(oldMethod());
}
上面的例子中如果oldMethod()足够快是没有什么问题的,但是如果很慢呢?调用oldMethod()将会阻塞住他所在的线程。
为了解决这个问题,可以参考我一直使用的方法–使用defer()来包装缓慢的代码:
private Object slowBlockingMethod() { ... }
public Observable<Object> newMethod() {
return Observable.defer(() -> Observable.just(slowBlockingMethod()));
}
现在,newMethod()的调用不会阻塞了,除非你订阅返回的observable对象。
调度器
使用RxJava,你可以使用subscribeOn()指定观察者代码运行的线程,使用observerOn()指定订阅者运行的线程:
//Subscriber前面执行的代码都是在I/O线程中运行。最后,操作view的代码在主线程中运行.
myObservableServices.retrieveImage(url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bitmap -> myImageView.setImageBitmap(bitmap));
可以把subscribeOn()和observerOn()添加到任何Observable对象上。这两个也是操作符。不需要关心Observable对象以及它上面有哪些操作符。仅仅运用这两个操作符就可以实现在不同的线程中调度。
订阅(Subscriptions)
当调用Observable.subscribe(),会返回一个Subscription对象。这个对象代表了被观察者和订阅者之间的联系。
ubscription subscription = Observable.just("Hello, World!")
.subscribe(s -> System.out.println(s));
你可以在后面使用这个Subscription对象来操作被观察者和订阅者之间的联系.
subscription.unsubscribe();
System.out.println("Unsubscribed=" + subscription.isUnsubscribed());
// Outputs "Unsubscribed=true"
RxJava的另外一个好处就是它处理 unsubscribing 的时候,会停止整个调用链。如果你使用了一串很复杂的操作符,调用 unsubscribe 将会在他当前执行的地方终止。不需要做任何额外的工作!