在之前三篇中已经对于RxJava2的各种使用及原理有了一定的了解了,接下来则通过手写实现的方式加强对于它的原理的掌握。
extend T>和 super T>阐述:
从是否可读可写角度说明:
在正式手写RxJava代码之前,需要先对其泛型知识做一个巩固,因为RxJava的源码中充斥着大量的泛型,先来贴一个源码中的一处代码:
其实核心就是要了解 extend T>和 super T>的使用场景,关于这块在当时学习Kolin时已经阐述得非常之清楚了,可以参考https://www.cnblogs.com/webor2006/p/11291744.html,总结一下就是 extend T>是协变,只能读,而 super T>是逆变,只能写。
说到这俩个泛型的区别,我记得在面试时问到候选人这个问题,基本上9成的回答是:“ extend T>代表只能传T的子类型; super T>代表只能传T的父类型。。”,这个回答等于把人当傻子,是个人看到都能说出这点,extend和super从编程语义上也能知道嘛,但是好的回答应该是从使用场景来道出这俩的不同以及怎么使用。
由于之前已经对于这块详细说明过,这里再简单的过一下,温故而知新~~
而如果修改一下:
再来修改:
当然可以强制转换倒是可以:
接着咱们添加试一下:
从函数定义角度说明:
extend T>,只能读不能写,很显然适合作为方法的返回值,比如:
super T>,只能写不能值,那适合当参数传递,如下:
总结:
如果你想从一个数据类型里获取数据,使用 ? extends 通配符(能取不能存)
如果你想把对象写入一个数据结构里,使用 ? super 通配符(能存不能取)
如果你既想存,又想取,那就别用通配符。
手写RxJava2核心实现:
接下来开启又兴奋又刺激的手撸环节:
框架搭建:
先来建一个文件夹,里面用来存放我们写手的RxJava框架代码:
然后先来定义一个被观察者类:
而看一下RxJava的源码,它其实是实现了一个接口的,如下:
所以校仿一下:
这里为啥是要 super T>,很明显是要将它做为参数传递的,接下来咱们来定义观察者,也是个接口:
packagecom.android.rxjavastudy;importcom.android.rxjavastudy.rxjava.Disposable;public interface Observer{voidonSubscribe(Disposable d);voidonNext(T t);voidonError(Throwable e);voidonComplete();
}
其中需要一个Disposable,它也是一个接口,定义如下:
packagecom.android.rxjavastudy.rxjava;public interfaceDisposable {void dispose(booleanbool);booleanisDisposed();
}
Observable.create():
接下来则来实现一下创建被观察者的逻辑,如下:
先来看一下它的定义,然后咱们再校仿一下:
咱们校仿着定义一下,其中勾子函数的代码一并忽略:
先来看一下源代码的定义:
校仿一下:
这里又来参考下源代码的定义:
所以接下来定义两个跟发射器相关的接口:
好,接下来则再来定义这个类:
此时咱们就可以调用咱们自己的编写的RxJava代码了,如下:
这里要来明白一种思想就是:
其实它里面是做了转换了的:
也就是对于源来的功能通过装饰则对原功能进行了加强。
订阅逻辑实现(subscribe):
接下来则要来实现最核心的订阅方法啦,也就是:
那它里面该怎么实现呢?依然先看源码:
所以照抄一下:
所以在ObservableCreate()中来具体实现之:
注意在子类中就木有必要重写subscribe()方法了,它统一由父类Observable来进行管理,那具体在子类中怎么来实现呢?
首先可以回调一下订阅成功的回调:
这里则需要再定义一下,在里面定义成一个内部类,如下:
public class ObservableCreate extends Observable{final ObservableOnSubscribesource;public ObservableCreate(ObservableOnSubscribesource) {this.source =source;
}
@Overrideprotected void subscribeActual(Observer super T>observer) {
CreateEmitter parent = new CreateEmitter<>(observer);
observer.onSubscribe(parent);
}static final class CreateEmitter implements ObservableEmitter, Disposable {
final Observer super T> observer;
private boolean bool;
public CreateEmitter(Observer super T> observer) {
this.observer = observer;
}
@Override
public void dispose(boolean bool) {
this.bool = bool;
}
@Override
public boolean isDisposed() {
return bool;
}
@Override
public void onNext(T value) {
if (!bool) {
observer.onNext(value); //observer === MapObserver
}
}
@Override
public void onError(Throwable throwable) {
if (!bool) {
observer.onError(throwable);
}
}
@Override
public void onComplete() {
if (!bool) {
observer.onComplete();
}
}
}
}
此时则会回调咱们的这个应用回调接口了:
好,接下来则应该来回调待观察者的回调方法,来对事件进行发送:
怎么调用呢?比较简单:
此时我们调用发射器的方法:
最终就是直接通过了我们在这定义的发射器的方法:
再转向到了我们的观察者的回调了:
原来是这么个流程,手写了一遍确实顺间另深了对RxJava调用流程的理解了。
运行看一下调用效果:
目前就可以来看一下调用效果了:
加入map操作符复杂实现:
在上面的实现中是一个最为简单的版本,这次准备实现一个map操作符的效果,最终效果如下:
别看只是简单的增加一个操作符,便是实际它内部实现也不是很简单的,下面开始:
新的一个操作符里面肯定又得重新封装一下,那具体怎么封装呢?先看一下源码的实现:
校仿一下,先来定义一个抽象类:
然后再来定义ObservableMap:
packagecom.android.rxjavastudy.rxjava;public class ObservableMap extends AbstractObservableWithUpstream{final Function super T, ? extends U>function;public ObservableMap(ObserverbleSource source, Function super T, ? extends U>function) {super(source);this.function =function;
}
@Overrideprotected void subscribeActual(Observer super U>observer) {//TODO
}
}
接下来则来生成这个包装类:
Function定义如下:
接下来则来实现ObservableMap这个被观察者的订阅方法,首先肯定也得先回调一下观察者的订阅成功的方法啦:
但是这里改变写法了,先来看一下源码这块的实现,可以参考一下:
其实回调观察者的订阅方法是放到了内部类的父类了,如下:
所以,校仿一下:
packagecom.android.rxjavastudy.rxjava;//观察者
public abstract class BasicFuseableObserver implements Observer, Disposable{//观察者
protected final Observer super R>actual;protectedDisposable disposeble;public BasicFuseableObserver(Observer super R>actual) {this.actual =actual;
}
@Overridepublic voidonSubscribe(Disposable d) {this.disposeble =d;
actual.onSubscribe(d);
}
@Overridepublic voidonError(Throwable e) {
actual.onError(e);
}
@Overridepublic voidonComplete() {
actual.onComplete();
}
@Overridepublic void dispose(booleanbool) {
disposeble.dispose(bool);
}
@Overridepublic booleanisDisposed() {returndisposeble.isDisposed();
}
}
注意此时的source是调用onCreate()操作符生成的被观察者,也就是ObservableCreate, 所以当调用:
则会转到它:
最后再又执行到了被观察者的事件回调方法:
好了,整个map操作符的代码就写完了,还是挺绕的,接下来咱们应用一下看下效果:
运行结果:
线程切换:
接下来则来完成一下线程的切换功能,我们之前已经清楚的知道了:
那对于map转换操作符是在哪个线程呢?其实它跟被观察者的回调是在同一个线程的,下面来打印一下验证一下:
运行:
确实map操作符跟被观察者的事件回调都是由subscribeOn来决定的线程,下面则来实现一下线程切换。
subscribeOn():
首先先来在观察者中定义这个方法:
此时咱们就给这个方法定义参数了,默认就让它在io线程里,先来调用一下它:
如之前的套路一样,这是一个新的操作符,又得做个被观察者的装饰,所以新建一个:
所以此时就可以实例化它了:
接下来则来处理包装被观察者的实现逻辑了,首先还是得先告诉观察者已经订阅成功了,又得有个观察者的包装,老套路如下:
packagecom.android.rxjavastudy.rxjava.observable;importcom.android.rxjavastudy.rxjava.Disposable;importcom.android.rxjavastudy.rxjava.Observer;importcom.android.rxjavastudy.rxjava.ObserverbleSource;//指定被观察者在那个线程运行的被观察者
public class ObservableSubscribeOn extends AbstractObservableWithUpstream{public ObservableSubscribeOn(ObserverbleSourcesource) {super(source);
}
@Overrideprotected void subscribeActual(Observer super T>observer) {//重新包装observer
final SubscribeOnObserver parent = new SubscribeOnObserver(observer);
//告诉下游观察者订阅成功observer.onSubscribe(parent);
}static final class SubscribeOnObserver implements Observer, Disposable {
final Observer super T> actual;
Disposable disposable;
public SubscribeOnObserver(Observer super T> actual) {
this.actual = actual;
}
@Override
public void dispose(boolean bool) {
this.disposable.dispose(bool);
}
@Override
public boolean isDisposed() {
return this.disposable.isDisposed();
}
@Override
public void onSubscribe(Disposable d) {
this.disposable = d;
}
@Override
public void onNext(T t) {
this.actual.onNext(t);
}
@Override
public void onError(Throwable e) {
this.actual.onError(e);
}
@Override
public void onComplete() {
this.actual.onComplete();
}
}
}
好,接下来就应该是回调被观察者的事件方法了,注意!!此时就需要进行线程的切换了,如下:
于此关于这个方法的逻辑就实现完了,是不是也不是很难?此时我们的map肯定也是在子线程啦,为啥?
好,接下来咱们来验证一下是否已经实现了此功能了:
运行:
但是!!此时next()回调的线程不对呀:
这是因为我们还没有实现observeOn(),所以接下来再来实现它。
observeOn():
同样的套路,就不多说了,直接贴出实现:
packagecom.android.rxjavastudy.rxjava.observable;importandroid.os.Handler;importandroid.os.Looper;importcom.android.rxjavastudy.rxjava.Disposable;importcom.android.rxjavastudy.rxjava.Observer;importcom.android.rxjavastudy.rxjava.ObserverbleSource;//指定观察者在那个线程运行的被观察者
public class ObservableObserveOn extends AbstractObservableWithUpstream{public ObservableObserveOn(ObserverbleSourcesource) {super(source);
}
@Overrideprotected void subscribeActual(Observer super T>observer) {
ObserverOnObserver parent = new ObserverOnObserver<>(observer);
source.subscribe(parent);
}//包装下游观察者,并关联onNext,..... 放入主线程中执行
static final class ObserverOnObserver implements Observer, Disposable {final Observer super T>actual;
Disposable disposeble;privateHandler handler;
ObserverOnObserver(Observer super T>actual) {this.actual =actual;
handler= newHandler(Looper.getMainLooper());
}
@Overridepublic void dispose(booleanbool) {this.disposeble.dispose(bool);
}
@Overridepublic booleanisDisposed() {return this.disposeble.isDisposed();
}
@Overridepublic voidonSubscribe(Disposable d) {this.disposeble =d;
actual.onSubscribe(d);
}
@Overridepublic void onNext(finalT t) {
handler.post(new Runnable() {
@Override
public voidrun() {
actual.onNext(t);
}
});
}
@Overridepublic void onError(finalThrowable e) {
handler.post(new Runnable() {
@Override
public voidrun() {
actual.onError(e);
}
});
}
@Overridepublic voidonComplete() {
handler.post(new Runnable() {
@Override
public voidrun() {
actual.onComplete();
}
});
}
}
}
嗯,比较简单,再来应用一下:
运行:
至此,手写RxJava的核心功能就到这,对它的原理了解得也更加透彻了。