最近新开的项目需要用到rxJava.在网上找了一下资料,感觉资料好少,有一些资料虽然有例子,但例子都好复杂,对一个新手来说操作是挺麻烦的.因此,本人根据自己的理解写了一些例子还有源码分析,给记忆力不好的自己,留作复习用,也希望能帮助大家.文章可能写得有点慢,请大家见谅.
本文的顺序是根据ReactiveX文档中文翻译来写的,该文档已经把一些概念性的东西讲得很清楚了,在这里我就不再讲述.如果有需要的话大家可以去看一下.
Observable的创建
1, create,代码如下:
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello,rxJava");
subscriber.onCompleted();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("---- onCompleted ----");
}
@Override
public void onError(Throwable e) {
System.out.println("---- onError ----");
}
@Override
public void onNext(String s) {
System.out.println("---- onNext ----:" + s);
}
});
运行结果如下:
---- onNext ----:hello,rxJava
---- onCompleted ----
通过该方创建Observable的话需要手动的去调用subscriber里面的方法如:onNext,onCompleted.onError一般是程序出现错误的时候,rxjava主动调用的,因此,正常情况下,不需要去调用.
create方法做了什么呢,下面我们去看一下源码,首先看到create方法的内部
源码分析:
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(hook.onCreate(f));
}
看到hook.onCreate(f)的onCreate内部
public <T> OnSubscribe<T> onCreate(OnSubscribe<T> f) {
return f;
}
直接返回了我们之前创建的OnSubscribe的实例对象.接着创建Observable对象并返回.
下面看subscribe方法的内部:
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
这里的this就是之前返回的Observable对象,继续看subscribe方法的内部:
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
... 省略部分
// subscriber每次都会首先调用onStart方法
subscriber.onStart();
// 这里把subscriber封装成一个安全的对象
// 在这里就不分析SafeSubscriber里面的代码了
// 因为里面的代码无非是通过try{}catch{}来保证整个流程正常执行
if (!(subscriber instanceof SafeSubscriber)) {
subscriber = new SafeSubscriber<T>(subscriber);
}
try {
// onSubscribeStart返回之前创建的observable.onSubscribe对象,并且调用call
hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
} catch (Throwable e) {
... 省略部分
// 合理就是如抛出异常之后的处理了
try {
subscriber.onError(hook.onSubscribeError(e));
}catch (Throwable e2) {
... 省略部分
}
// 从这也可以知道,如果有异常抛出的话,rxjava会为我们取消订阅
return Subscriptions.unsubscribed();
}
}
这里需要注意的是subscriber = new SafeSubscriber(subscriber);这一句代码,我就简单的说一下这样做的原因:主要是为了防止用户创建的subscriber抛出异常导致整个流程不能正常运行.具体理由大家可以点击该链接,这里有详细的讨论.
2, Defer,代码如下:
Observable.defer(new Func0<Observable<String>>() {
@Override
public Observable call() {
// 这里要返回一个Observable的实例对象,在这里用create的方法创建
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
// 这里还是create的用法
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello world");
subscriber.onCompleted();
}
});
}
// 然后这里是订阅者,跟create一样
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("---- onCompleted ----");
}
@Override
public void onError(Throwable e) {
System.out.println("---- onError ----");
}
@Override
public void onNext(String o) {
System.out.println("---- onNext ----" + o);
}
});
---- onNext ----hello world
---- onCompleted ----
该方法从用法还是结果来看基本和create一样,并且还多了new Func0 <Observable>(){}这么一个步骤. 看起来比create还麻烦.它内部的实现与create有什么异同呢.下面我们看一下defer这个方法的内部实现.
源码分析:
public static <T> Observable<T> defer(Func0<Observable<T>> observableFactory) {
return create(new OnSubscribeDefer<T>(observableFactory));
}
看到这个方法之前我们new Func0对象变成了一个observable的创建工厂observableFactory.接着看OnSubscribeDefer这个类的内部,知道这个OnSubscribeDefer,实现的是OnSubscribe接口:
public final class OnSubscribeDefer<T> implements OnSubscribe<T>
该类把我们之前创建的Func0对象保存起来
public OnSubscribeDefer(Func0<? extends Observable<? extends T>> observableFactory) {
this.observableFactory = observableFactory;
}
这样也可以看出defer方法返回的是OnSubscribeDefer的对象.因此在subscribe调用的是该实例的call方法,因此去看该类的的call方法:
@Override
public void call(final Subscriber<? super T> s) {
Observable<? extends T> o;
try {
// 这里调用了 Func0对象的call方法,返回了我们用过create创建的
// Observable实例
o = observableFactory.call();
} catch (Throwable t) {
Exceptions.throwOrReport(t, s);
return;
}
// 然后再这里调用create里面的方法call
// 这里的unsafeSubscribe从源码可知
// 没有把Subscriber对象包装为SafeSubscriber
o.unsafeSubscribe(Subscribers.wrap(s));
}
继续去看unsafeSubscribe的源码:
public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
try {
... 忽略部分
subscriber.onStart();
hook.onSubscribeStart(this, onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
} catch (Throwable e) {
... 忽略部分
try {
subscriber.onError(hook.onSubscribeError(e));
} catch (Throwable e2) {
... 忽略部分
}
return Subscriptions.unsubscribed();
}
}
该方法跟我们之前分析的subscribe基本是一样的,除了没有把subscriber对象包装成SafeSubscriber对象之外.
defer的整个流程可以总结为:调用defer的时候并没有直接创建Observable的实例对象,而是在调用subscribe时候才通过observableFactory来创建.至于它的用处,等我们讲到just的时候才回过头来看.
3, empty,代码如下:
Observable.empty().subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.println("---- onCompleted ----");
}
@Override
public void onError(Throwable e) {
System.out.println("---- onError ----");
}
@Override
public void onNext(Object o) {
System.out.println("---- onNext ----");
}
});
结果如下:
---- onCompleted ----
从运行结果看,通empty创建的Observable值调用onCompleted方法,不调用onNext:
源码分析:
empty方法内部:
public static <T> Observable<T> empty() {
return EmptyObservableHolder.instance();
}
跟进EmptyObservableHolder.instance(),发现EmptyObservableHolder是一个枚举类:
public enum EmptyObservableHolder implements OnSubscribe<Object> {
INSTANCE
...忽略部分
}
而instance方法内容如下:
public static <T> Observable<T> instance() {
return (Observable<T>)EMPTY;
}
该方法返回了枚举类里面的INSTANCE.
因此subscribe方法里面调用的是该类的call方法了,看到该枚举类里面的call方法:
@Override
public void call(Subscriber<? super Object> child) {
child.onCompleted();
}
从这里可以知道为什么empty创建的Observable对象只调用了onCompleted方法的原因了;
4, Never,代码如下:
Observable.never().subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.println("---- onCompleted ----");
}
@Override
public void onError(Throwable e) {
System.out.println("---- onError ----");
}
@Override
public void onNext(Object o) {
System.out.println("---- onNext ----");
}
});
运行该代码片段时,什么输出都没有.
源码分析如下:
跟进never方法看到:
public static <T> Observable<T> never() {
return NeverObservableHolder.instance();
}
根据之前empty分析可以判断出NeverObservableHolder也是一个枚举类,该类里面的call方法代码如下:
@Override
public void call(Subscriber<? super Object> child) {
}
从这里看到该call方法执行内容为空,这就是never什么都不执行的原因了.
5, error,代码如下:
Observable.error(new Exception("hello I'm error")).subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.println("---- onCompleted ----");
}
@Override
public void onError(Throwable e) {
System.out.println("---- onError ----" + e.getMessage());
}
@Override
public void onNext(Object o) {
System.out.println("---- onNext ----");
}
});
运行结果如下:
---- onError ----hello I'm error
这里的异常信息就是通过error创建Observable时传入异常的信息.
源码分析如下:
error方法内部:
public static <T> Observable<T> error(Throwable exception) {
return create(new OnSubscribeThrow<T>(exception));
}
跟进OnSubscribeThrow,看到该类的call方法
@Override
public void call(Subscriber<? super T> observer) {
observer.onError(exception);
}
可以看到该类的call方法直接调用onError方法并且传入我们之前的创建的Exception.
好了第一部分就先分析到这里了,如果大家有什么不明白的,或者认为我讲得不合理的都可以给我留言.