在之前三篇中已经对于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>,很明显是要将它做为参数传递的,接下来咱们来定义观察者,也是个接口:
package com.android.rxjavastudy;
import com.android.rxjavastudy.rxjava.Disposable;
public interface Observer<T> {
void onSubscribe(Disposable d);
void onNext(T t);
void onError(Throwable e);
void onComplete();
}
其中需要一个Disposable,它也是一个接口,定义如下:
package com.android.rxjavastudy.rxjava;
public interface Disposable {
void dispose(boolean bool);
boolean isDisposed();
}
Observable.create():
接下来则来实现一下创建被观察者的逻辑,如下:
先来看一下它的定义,然后咱们再校仿一下:
咱们校仿着定义一下,其中勾子函数的代码一并忽略:
先来看一下源代码的定义:
校仿一下:
这里又来参考下源代码的定义:
所以接下来定义两个跟发射器相关的接口:
好,接下来则再来定义这个类:
此时咱们就可以调用咱们自己的编写的RxJava代码了,如下:
这里要来明白一种思想就是:
其实它里面是做了转换了的:
也就是对于源来的功能通过装饰则对原功能进行了加强。
订阅逻辑实现(subscribe):
接下来则要来实现最核心的订阅方法啦,也就是:
那它里面该怎么实现呢?依然先看源码:
所以照抄一下:
所以在ObservableCreate()中来具体实现之:
注意在子类中就木有必要重写subscribe()方法了,它统一由父类Observable来进行管理,那具体在子类中怎么来实现呢?
首先可以回调一下订阅成功的回调:
这里则需要再定义一下,在里面定义成一个内部类,如下:
public class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<>(observer);
observer.onSubscribe(parent);
}
static final class CreateEmitter<T> implements ObservableEmitter<T>, 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:
package com.android.rxjavastudy.rxjava;
public class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObserverbleSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
protected void subscribeActual(Observer<? super U> observer) {
//TODO
}
}
接下来则来生成这个包装类:
Function定义如下:
接下来则来实现ObservableMap这个被观察者的订阅方法,首先肯定也得先回调一下观察者的订阅成功的方法啦:
但是这里改变写法了,先来看一下源码这块的实现,可以参考一下:
其实回调观察者的订阅方法是放到了内部类的父类了,如下:
所以,校仿一下:
package com.android.rxjavastudy.rxjava;
//观察者
public abstract class BasicFuseableObserver<T, R> implements Observer<T>, Disposable<R> {
//观察者
protected final Observer<? super R> actual;
protected Disposable disposeble;
public BasicFuseableObserver(Observer<? super R> actual) {
this.actual = actual;
}
@Override
public void onSubscribe(Disposable d) {
this.disposeble = d;
actual.onSubscribe(d);
}
@Override
public void onError(Throwable e) {
actual.onError(e);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void dispose(boolean bool) {
disposeble.dispose(bool);
}
@Override
public boolean isDisposed() {
return disposeble.isDisposed();
}
}
注意此时的source是调用onCreate()操作符生成的被观察者,也就是ObservableCreate, 所以当调用:
则会转到它:
最后再又执行到了被观察者的事件回调方法:
好了,整个map操作符的代码就写完了,还是挺绕的,接下来咱们应用一下看下效果:
运行结果:
线程切换:
接下来则来完成一下线程的切换功能,我们之前已经清楚的知道了:
那对于map转换操作符是在哪个线程呢?其实它跟被观察者的回调是在同一个线程的,下面来打印一下验证一下:
运行:
确实map操作符跟被观察者的事件回调都是由subscribeOn来决定的线程,下面则来实现一下线程切换。
subscribeOn():
首先先来在观察者中定义这个方法:
此时咱们就给这个方法定义参数了,默认就让它在io线程里,先来调用一下它:
如之前的套路一样,这是一个新的操作符,又得做个被观察者的装饰,所以新建一个:
所以此时就可以实例化它了:
接下来则来处理包装被观察者的实现逻辑了,首先还是得先告诉观察者已经订阅成功了,又得有个观察者的包装,老套路如下:
package com.android.rxjavastudy.rxjava.observable;
import com.android.rxjavastudy.rxjava.Disposable;
import com.android.rxjavastudy.rxjava.Observer;
import com.android.rxjavastudy.rxjava.ObserverbleSource;
//指定被观察者在那个线程运行的被观察者
public class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
public ObservableSubscribeOn(ObserverbleSource<T> source) {
super(source);
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
//重新包装observer
final SubscribeOnObserver parent = new SubscribeOnObserver(observer);
//告诉下游观察者订阅成功
observer.onSubscribe(parent);
}
static final class SubscribeOnObserver<T> implements Observer<T>, Disposable {
final Observer<? super T> actual;
Disposable<T> 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():
同样的套路,就不多说了,直接贴出实现:
package com.android.rxjavastudy.rxjava.observable;
import android.os.Handler;
import android.os.Looper;
import com.android.rxjavastudy.rxjava.Disposable;
import com.android.rxjavastudy.rxjava.Observer;
import com.android.rxjavastudy.rxjava.ObserverbleSource;
//指定观察者在那个线程运行的被观察者
public class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
public ObservableObserveOn(ObserverbleSource<T> source) {
super(source);
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
ObserverOnObserver<T> parent = new ObserverOnObserver<>(observer);
source.subscribe(parent);
}
//包装下游观察者,并关联onNext,..... 放入主线程中执行
static final class ObserverOnObserver<T> implements Observer<T>, Disposable {
final Observer<? super T> actual;
Disposable disposeble;
private Handler handler;
ObserverOnObserver(Observer<? super T> actual) {
this.actual = actual;
handler = new Handler(Looper.getMainLooper());
}
@Override
public void dispose(boolean bool) {
this.disposeble.dispose(bool);
}
@Override
public boolean isDisposed() {
return this.disposeble.isDisposed();
}
@Override
public void onSubscribe(Disposable d) {
this.disposeble = d;
actual.onSubscribe(d);
}
@Override
public void onNext(final T t) {
handler.post(new Runnable() {
@Override
public void run() {
actual.onNext(t);
}
});
}
@Override
public void onError(final Throwable e) {
handler.post(new Runnable() {
@Override
public void run() {
actual.onError(e);
}
});
}
@Override
public void onComplete() {
handler.post(new Runnable() {
@Override
public void run() {
actual.onComplete();
}
});
}
}
}
嗯,比较简单,再来应用一下:
运行:
至此,手写RxJava的核心功能就到这,对它的原理了解得也更加透彻了。