RxJava 拥有繁多的 API 和复杂的逻辑链,学习复杂的知识,一般从整体再到具体,为了学习 RxJava 的原理,参考其源码,自己动手实现一个简化的 RxJava,旨在理解调用链
阅读本文,建议先下载代码 SimpleRx,毕竟在IDE里阅读代码比在网页上要清晰得多,也可以看下打印的日志
最主要的4个类:Observable、OnSubscribe、Operator、Subscriber
1、最简单的,创建一个Observable,然后订阅
Observable
.create(new OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
subscriber.onNext(1);
}
})
.subscribe(new Subscriber() {
@Override
public void onNext(Integer integer) {
System.out.println(integer);
}
});
public class Observable {
private OnSubscribe onSubscribe;
private Observable(OnSubscribe onSubscribe) {
this.onSubscribe = onSubscribe;
}
public final void subscribe(Subscriber super T> subscriber) {
onSubscribe.call(subscriber);
}
public static Observable create(OnSubscribe onSubscribe) {
return new Observable<>(onSubscribe);
}
}
这里可以看出 subscribe(subscriber)-->onSubscribe.call(subscriber),所以没有订阅动作就不会触发 OnSubscribe.call()
2、map 和 lift
Observable
.create(new OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
subscriber.onNext(1);
}
})
.map(new Func1() {
@Override
public String call(Integer integer) {
return "map" + integer;
}
})
.subscribe(new Subscriber() {
@Override
public void onNext(String s) {
System.out.println(s);
}
});
非链式的写法
OnSubscribe onSubscribe = new OnSubscribe<>();
Observable observable = Observable.create(onSubscribe);
Func1 func = new Func1<>();
Observable observable2 = observable.map(func);
Subscriber subscriber = new Subscriber<>();
observable2.subscribe(subscriber);
create() 跟之前一样,那么 map() 做了什么
public final Observable map(Func1 super T, ? extends R> func) {
return lift(new OperatorMap(func));
}
public final Observable lift(final Operator extends R, ? super T> operator) {
return new Observable(new OnSubscribeLift(onSubscribe, operator));
}
lift() 根据上一个 observable 的 onSubscribe 创建一个新的 OnSubscribeLift 返回一个新的 observable2,上面我们说过 subscribe(subscriber)-->onSubscribe.call(subscriber),所以我们接着看 OnSubscribeLift
public class OnSubscribeLift implements OnSubscribe {
final OnSubscribe parent;
final Operator extends R, ? super T> operator;
public OnSubscribeLift(OnSubscribe parent, Operator extends R, ? super T> operator) {
this.parent = parent;
this.operator = operator;
}
// 先不用关心具体实现,下面讲到再看
@Override
public void call(Subscriber super R> r) {
Subscriber super T> st = operator.call(r); // 这个 operator 就是 OperatorMap
parent.call(st); // parent 就是第一个 observable 的 onSubscribe
}
}
再看下 OperatorMap
public final class OperatorMap implements Operator {
final Func1 super T, ? extends R> transformer;
public OperatorMap(Func1 super T, ? extends R> transformer) {
this.transformer = transformer;
}
// 先不用关心具体实现,下面讲到再看
@Override
public Subscriber super T> call(final Subscriber super R> o) {
return new MapSubscriber(o, transformer);
}
private class MapSubscriber extends Subscriber {
private Subscriber super R> actual;
private Func1 super T, ? extends R> transformer;
public MapSubscriber(Subscriber super R> o, Func1 super T, ? extends R> transformer) {
this.actual = o;
this.transformer = transformer;
}
// 先不用关心具体实现,下面讲到再看
@Override
public void onNext(T t) {
R r = transformer.call(t);
actual.onNext(r);
}
}
}
我们把 map() 和 lift() 都去掉,使用最基本的类来实现
OnSubscribe onSubscribe = new OnSubscribe<>();
Observable observable = new Observable<>(onSubscribe);
Func1 func = new Func1<>();
OperatorMap operatorMap = new OperatorMap<>(func);
OnSubscribeLift onSubscribe2 = new OnSubscribeLift<>(onSubscribe, operatorMap);
Observable observable2 = new Observable<>(onSubscribe2);
Subscriber subscriber = new Subscriber<>();
observable2.subscribe(subscriber);
到这里,清楚了如何把第一个 Observable
那么最终的 subscribe() 如何调用到第一个 observable.call(Subscriber
**1) observable2.subscribe(subscriber) -->
- onSubscribe2.call(subscriber) 即 OnSubscribeLift.call(subscriber) -->
- Subscriber
st = operatorMap.call(subscriber) 即 - Subscriber
st = new MapSubscriber (subscriber, func) - parent.call(st) 即 onSubscribe.call(st) -->
- st.onNext(1) 即 MapSubscriber.onNext(1) -->
- String string = func.call(1)
- subscriber.onNext(string)**
至此 Observable.create().map().subscribe() 的调用链就分析完了
很多操作符本质都是 lift(),以此类推,lift() 2次
3、subscribeOn
Scheduler 内部比较繁杂,我们简化下,把 subscribeOn(Scheduler) 简化成 subscribeOnIO()
Observable
.create(new OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
subscriber.onNext(1);
}
})
.subscribeOnIO()
.subscribe(new Subscriber() {
@Override
public void onNext(Integer integer) {
System.out.println(integer);
}
});
如何实现 subscribeOnIO() 让第一个 observable 的 onSubscribe 运行在子线程
public final Observable subscribeOnIO() {
return create(new OnSubscribeOnIO(this));
}
public final class OnSubscribeOnIO implements OnSubscribe {
private static ExecutorService threadPool = Executors.newCachedThreadPool();
final Observable source;
public OnSubscribeOnIO(Observable source) {
this.source = source;
}
@Override
public void call(final Subscriber super T> subscriber) {
Runnable runnable = new Runnable() {
@Override
public void run() {
source.subscribe(subscriber); // --> onSubscribe.call(subscriber) --> subscriber.onNext(1)
}
};
threadPool.submit(runnable);
}
}
从上面看出 subscribeOnIO() 新建了一个线程并加入 CachedThreadPool,在子线程里订阅上一个 Observable,后续的调用都在这个线程里完成
再考虑下复杂点的,加入 map()
Observable
.create(new OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
System.out.println(Thread.currentThread());
subscriber.onNext(1);
}
})
.map(new Func1() {
@Override
public String call(Integer integer) {
System.out.println(Thread.currentThread());
return "map" + integer;
}
})
.subscribeOnIO()
.subscribe(new Subscriber() {
@Override
public void onNext(String s) {
System.out.println(Thread.currentThread());
System.out.println(s);
}
});
非链式的写法
OnSubscribe onSubscribe = new OnSubscribe<>();
Observable observable = new Observable<>(onSubscribe);
Func1 func = new Func1<>();
OperatorMap operatorMap = new OperatorMap<>(func);
OnSubscribeLift onSubscribe2 = new OnSubscribeLift<>(onSubscribe, operatorMap);
Observable observable2 = new Observable<>(onSubscribe2);
OnSubscribeOnIO onSubscribe3 = new OnSubscribeOnIO(observable2);
Observable observable3 = new Observable<>(onSubscribe3);
Subscriber subscriber = new Subscriber<>();
observable3.subscribe(subscriber);
**1) observable3.subscribe(subscriber) -->
- onSubscribe3.call(subscriber) 即 OnSubscribeOnIO.call(subscriber) -->
- 子线程 new Runnable(){} --> observable2.subscribe(subscriber)
- onSubscribe2.call(subscriber) 即 OnSubscribeLift.call(subscriber) -->
- Subscriber
st = operatorMap.call(subscriber) 即 - Subscriber
st = new MapSubscriber (subscriber, func) - parent.call(st) 即 onSubscribe.call(st) -->
- st.onNext(1) 即 MapSubscriber.onNext(1) -->
- String string = func.call(1)
- subscriber.onNext(string)**
那要是把 map() 与 subscribeOnIO() 换下位置呢
OnSubscribe onSubscribe = new OnSubscribe<>();
Observable observable = new Observable<>(onSubscribe);
OnSubscribeOnIO onSubscribe2 = new OnSubscribeOnIO(observable);
Observable observable2 = new Observable<>(onSubscribe2);
Func1 func = new Func1<>();
OperatorMap operatorMap = new OperatorMap<>(func);
OnSubscribeLift onSubscribe3 = new OnSubscribeLift<>(onSubscrib2, operatorMap);
Observable observable3 = new Observable<>(onSubscribe3);
Subscriber subscriber = new Subscriber<>();
observable3.subscribe(subscriber);
**1) observable3.subscribe(subscriber) -->
- onSubscribe3.call(subscriber) 即 OnSubscribeLift.call(subscriber) -->
- Subscriber
st = operatorMap.call(subscriber) 即 - Subscriber
st = new MapSubscriber (subscriber, func) - parent.call(st) 即 onSubscribe2.call(st) 即 OnSubscribeOnIO.call(st) -->
- 子线程 new Runnable(){} --> observable.subscribe(st) -->
- onSubscribe.call(st) -->
- st.onNext(1) 即 MapSubscriber.onNext(1) -->
- String string = func.call(1)
- subscriber.onNext(string)**
看得出来,不管 subscribeOnIO() 在哪,第一个 onSubscribe.call() 总是运行在子线程
4、observeOn
先看下 demo 最终写法
Handler handler = new Handler();
Observable
.create(new OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
subscriber.onNext(1);
}
})
.observeOn(handler)
.map(new Func1() {
@Override
public String call(Integer integer) {
return "map" + integer;
}
})
.subscribeOnIO()
.subscribe(new Subscriber() {
@Override
public void onNext(String s) {
System.out.println(s);
}
});
handler.loop(); //队列没有消息时会挂起当前线程,直到收到新的消息
同样我们也自己实现一个简单的可以切换回主线程的 observeOn(Handler)
public class Observable {
...
public final Observable observeOn(Handler handler) {
return lift(new OperatorObserveOn(handler));
}
}
OperatorObserveOn
public final class OperatorObserveOn implements Operator {
private Handler handler;
public OperatorObserveOn(Handler handler) {
this.handler = handler;
}
@Override
public Subscriber super T> call(final Subscriber super T> subscriber) {
Subscriber s = new Subscriber() {
@Override
public void onNext(final T t) {
handler.post(new Runnable() {
@Override
public void run() {
subscriber.onNext(t);
}
});
}
};
return s;
}
}
自定义Handler
public class Handler {
private ArrayBlockingQueue queue = new ArrayBlockingQueue(10);
public void loop() {
for (; ; ) {
Runnable runnable;
try {
runnable = queue.take();// 没有数据则一直阻塞,直到有数据自动唤醒
} catch (InterruptedException e) {
return;
}
if (runnable == null) {
return;
}
runnable.run();
}
}
public void post(Runnable runnable) {
try {
queue.put(runnable);// 没有空间则一直阻塞,直到有空间
} catch (InterruptedException e) {
return;
}
}
}
非链式写法
OnSubscribe onSubscribe = new OnSubscribe<>();
Observable observable = new Observable<>(onSubscribe);
OperatorObserveOn operatorObserveOn = new OperatorObserveOn(handler);
OnSubscribeLift onSubscribe2 = new OnSubscribeLift<>(onSubscribe, operatorObserveOn);
Func1 func = new Func1<>();
OperatorMap operatorMap = new OperatorMap<>(func);
OnSubscribeLift onSubscribe3 = new OnSubscribeLift<>(onSubscribe2, operatorMap);
Observable observable2 = new Observable<>(onSubscribe3);
OnSubscribeOnIO onSubscribe4 = new OnSubscribeOnIO(observable2);
Observable observable3 = new Observable<>(onSubscribe4);
Subscriber subscriber = new Subscriber<>();
observable3.subscribe(subscriber);
**1) observable3.subscribe(subscriber) -->
- onSubscribe4.call(subscriber) 即 OnSubscribeOnIO.call(subscriber) -->
- 子线程 new Runnable(){} --> observable2.subscribe(subscriber)
- onSubscribe3.call(subscriber) 即 OnSubscribeLift.call(subscriber) -->
- Subscriber
st = operatorMap.call(subscriber) 即 - Subscriber
st = new MapSubscriber (subscriber, func) - parent.call(st) 即 onSubscribe2.call(st) 即 OnSubscribeLift.call(st)-->
- Subscriber
st2 = operatorObserveOn.call(st) --> - parent.call(st2) 即 onSubscribe.call(st2) -->
- st2.onNext(1) --> // onNext()里面切换到Handler所在线程
- st.onNext(1) -->
- String string = func.call(1)
- subscriber.onNext(string)**
5、其他
总的来说,调用链确实有点复杂,不过也还是可以接受的,一个调用链花点时间想想还是能清楚,只是每碰到一个调用链都要花点时间才能想清楚,还没能力能在几秒内就能想清楚,只能是多想多锻炼了。比如想想上面的,如果把 observeOn(handler) 放在 map() 后面呢