RxJava
最近工作中使用了RxJava,于是阅读了一下RxJava的源码,方便理解和使用RxJava。
主要两个优势
- 方便的线程调度
- 方便高效的数据转化
转载请保留原文链接:http://blog.youkuaiyun.com/u010593680/article/details/53896316
先给一个简单的使用数据转化的例子:
Observable.just("string")
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return s.hashCode();
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("value : " + integer);
}
});
上面的例子是将String转化成Integer的例子,接下来开始分析执行流程
后面会分析各个方法的实现:
RxJava整体代码结构:生产者消费者模式
生产者就是创造数据的对象:例如just方法就是产生数据的方法,生产出来的数据才能够进行数据转化、给监听者subscriber消费
消费者:subscriber,用户调用的subscribe()设置的监听者
public static <T> Observable<T> just(final T value) {
return ScalarSynchronousObservable.create(value);
}
在ScalarSynchronousObservable中只是调用了设置onSubscribe为JustOnSubscribe
protected ScalarSynchronousObservable(final T t) {
super(hook.onCreate(new JustOnSubscribe<T>(t)));
this.t = t;
}
在JustOnSubscribe中设置了监听者subscriber的生产者
static final class JustOnSubscribe<T> implements OnSubscribe<T> {
final T value;
JustOnSubscribe(T value) {
this.value = value;
}
@Override
public void call(Subscriber<? super T> s) {
s.setProducer(createProducer(s, value));
}
}
看下createProducer方法:
static <T> Producer createProducer(Subscriber<? super T> s, T v) {
if (STRONG_MODE) {//默认为false
return new SingleProducer<T>(s, v);
}
return new WeakSingleProducer<T>(s, v);
}
SingleProducer和WeakSingleProducer操作流程基本一样,只是SingleProducer是线程安全的
static final class WeakSingleProducer<T> implements Producer {
final Subscriber<? super T> actual;
final T value;
boolean once;
public WeakSingleProducer(Subscriber<? super T> actual, T value) {
this.actual = actual;
this.value = value;
}
@Override
public void request(long n) {//数据产生后会调用该方法
if (once) {
return;
}
if (n < 0L) {
throw new IllegalStateException("n >= required but it was " + n);
}
if (n == 0L) {
return;
}
once = true;
Subscriber<? super T> a = actual;
if (a.isUnsubscribed()) {//如果已经解绑了,就不处理了
return;
}
T v = value;
try {
a.onNext(v);
} catch (Throwable e) {
Exceptions.throwOrReport(e, a, v);//有异常会调用OnError
return;
}
if (a.isUnsubscribed()) {
return;
}
a.onCompleted();//执行完onNet,没异常就执行onCompleted
}
}
前面为上游生产者代码,较为简单,就不细讲了,还是把重点放在比较重要的方法上
subscribe方法:使rxjava操作开始执行
subscribe前的方法调用只是作为设置,只有当subscribe方法被调用,所设置的操作才会被开始执行。来看下为什么
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
// 必须有监听者
if (subscriber == null) {
throw new IllegalArgumentException("subscriber can not be null");
}
if (observable.onSubscribe == null) {//必须有操作,如just的生产者操作
throw new IllegalStateException("onSubscribe function can not be null.");
/*
* the subscribe function can also be overridden but generally that's not the appropriate approach
* so I won't mention that in the exception
*/
}
// 开始调用监听者的方法
subscriber.onStart();
/*
* See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
* to user code from within an Observer"
*/
// if not already wrapped
if (!(subscriber instanceof SafeSubscriber)) {//转化为SafeSubscriber
// assign to `observer` so we return the protected version
subscriber = new SafeSubscriber<T>(subscriber);
}
// The code below is exactly the same an unsafeSubscribe but not used because it would
// add a significant depth to already huge call stacks.
try {
// allow the hook to intercept and/or decorate
hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);//调用observable.onSubscribe的call方法
return hook.onSubscribeReturn(subscriber);
} catch (Throwable e) {
// special handling for certain Throwable/Error/Exception types
Exceptions.throwIfFatal(e);
// in case the subscriber can't listen to exceptions anymore
if (subscriber.isUnsubscribed()) {
RxJavaPluginUtils.handleException(hook.onSubscribeError(e));
} else {
// if an unhandled error occurs executing the onSubscribe we will propagate it
try {
subscriber.onError(hook.onSubscribeError(e));
} catch (Throwable e2) {
Exceptions.throwIfFatal(e2);
// if this happens it means the onError itself failed (perhaps an invalid function implementation)
// so we are unable to propagate the error correctly and will just throw
RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
// TODO could the hook be the cause of the error in the on error handling.
hook.onSubscribeError(r);
// TODO why aren't we throwing the hook's return value.
throw r;
}
}
return Subscriptions.unsubscribed();
}
}
subscribe方法代码实际上只是进行了以下操作:
* 调用subscriber.onStart();
* 将subscriber转化为SafeSubscriber
* 调用observable.onSubscribe.call(subscriber),onSubscribe就是实际的线程调度,数据转化等操作的包装对象,此时这些操作才会真正执行。
* 异常处理
SafeSubscriber的onCompleted,onError方法都会调用unsubscribe();所以只有需要提前结束时才需要调用unsubscriber()
public class SafeSubscriber extends Subscriber {
private final Subscriber<? super T> actual;
boolean done = false;
public SafeSubscriber(Subscriber<? super T> actual) {
super(actual);
this.actual = actual;
}
/**
* Notifies the Subscriber that the {@code Observable} has finished sending push-based notifications.
* <p>
* The {@code Observable} will not call this method if it calls {@link #onError}.
*/
@Override
public void onCompleted() {
if (!done) {
done = true;
try {
actual.onCompleted();
} catch (Throwable e) {
// we handle here instead of another method so we don't add stacks to the frame
// which can prevent it from being able to handle StackOverflow
Exceptions.throwIfFatal(e);
RxJavaPluginUtils.handleException(e);
throw new OnCompletedFailedException(e.getMessage(), e);
} finally {
try {
// Similarly to onError if failure occurs in unsubscribe then Rx contract is broken
// and we throw an UnsubscribeFailureException.
unsubscribe();
} catch (Throwable e) {
RxJavaPluginUtils.handleException(e);
throw new UnsubscribeFailedException(e.getMessage(), e);
}
}
}
}
map(operator)转化操作
map操作需要Lift帮助实现的,这里先说map的转化操作
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return lift(new OperatorMap<T, R>(func));
}
关键代码在OperatorMap的call中:
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
//包装下游的subscriber生成新的MapSubscriber,
//以后生产者生产出产品后会先调用MapSubscriber的onNext等方法
o.add(parent);
return parent;
}
map方法的call方法把subcriber包装成一个
MapSubscriber,而真正的数据转化在MapSubscriber中完成的。
public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
this.actual = actual;
this.mapper = mapper;
}
@Override
public void onNext(T t) {
R result;
try {
result = mapper.call(t);//先执行map中用户定义的转化操作
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
unsubscribe();
onError(OnErrorThrowable.addValueAsLastCause(ex, t));
return;
}
actual.onNext(result);//将转化后的值交给下游继续处理
}
Lift操作
上部份代码还是比较容易理解的,只是有个问题就是: map操作在传入subcriber之前, 为什么map能包装到 下游的subcriber?
这个事情主要是lift方法中进行的转化
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
每次都新建一个Observable,Observable再将OnSubscribeLift保存到onSubscribe,也就是新lift对onSubscribe进行了包装
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
新的onSubscribe变成了OnSubscribeLift,在OnSubscribeLift类中call方法,call方法在subscribe()方法调用时,就会调用OnSubscribeLift的call方法,同时传入subscriber,那么OnSubscribeLift就获取到了下游的subscriber,之后OnSubscribeLift
@Override
public void call(Subscriber<? super R> o) {
try {
Subscriber<? super T> st = hook.onLift(operator).call(o);//hook默认操作就是return operator;相当于没有进行操作,所以这句代码默认为operator.call(o),这个operator可以是各种数据转化的操作,包括[下一篇的线程调度observeOn](http://blog.youkuaiyun.com/u010593680/article/details/53911475)切换线程操作
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
parent.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
每次都会新建一个Observable,并传入OnSubscribeLift作为构造函数参数
主要实现在OnSubscribeLift,在call方法中进行:
1. 调用当前数据转化操作的call方法,获得返回参数Subscriber
2. 调用Subscriber的onStart方法
3. 执行之前的onSubscribe的call方法,并传入1中返回值
上面的操作基本上就是模拟subscribe()完成的事,让Subscriber的生命周期完整
just方法是 生产者 :新建一个Observable,Observable保存了数据,生成了onSubscribe其onSubscibe只是简单的生产了数据,调用下游的subscriber的onNext等方法
梳理例子的运行过程:
- just新建一个Observable,Observable保存了数据,生成了onSubscribe其onSubscibe只是简单的生存了数据,调用下游的subscriber的onNext等方法
- map操作用了Lift新建一个Observable,该Observable的OnSubscribe保存了数据转化的操作
subscribe( subscriber )方法:调用上面操作生成的Observable.onSubscribe的call方法,并传入subscriber,即相当于上一步的lift操作 - lift操作先调用map的call方法包装subscriber方法,生成mapSubscriber
- 接着,lift操作调用了just生成的onSubscribe的call方法,于是数据生成,调用下游的subscriber(即mapSubscriber)的onNext方法
map进行了数据转化,并把转化后的值传到被包装的subscriber的onNext方法 - 结束