RxJava出来也有几年了,相信大家在敲代码的时候或多或少都会用到吧。我们发现在用的时候确实很方便,很多繁琐的代码如果用RxJava来操作的话,几行就可以搞定,而且逻辑清晰,界面干净。但是有多少童鞋对他的内核了解呢。相信有很大一部分童鞋是没有看过他的源码吧。归结几大原因:
1.工作太忙,没时间。
2.里面涉及很多T,R,看不懂,也不想看。
3.懒,对的,就是懒,懒,懒!(哈哈)。
起初我也想看,但是没看,最初的原因是2跟3(斜眼笑).但是现在发现这个东西太有意思了,所以再来看一遍,不过现在来看的话,发现可以很快就可以弄懂他的内部原理了。
那么接下来就来看看他们的内部原理吧,RxJava准备分几篇文章来讲,而且也不会是所有的操作符都讲到,会着重讲我们常用的,以及使用的时候我们难以区分的操作符。
Create操作符
我们先看一个例子:
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("hello");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
System.out.println("==>"+s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
我们以这个例子来讲解,首先我们看看create函数,
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
简简单单两行代码,第一行代码是对source对象判空,这个无须解释。重点在第二行,也就是说
RxJavaPlugins.onAssembly(new ObservableCreate<T>(source))返回一个Observable对象,那么就看看onAssembly方法,
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
在这个方法中,显然f对象是为空的,所以在这里只是返回source对象,而这个对象是ObservaleCreate实例,那么我们就去看看这个类,
public final 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<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);
} finally {
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
...
}
我们发现这个类是继承自Observable的,所以在create方法中返回他也是OK的,第一个调用就先到此为止。我们接着看第二段代码,subscribe方法,也就是订阅方法了,我们进入到该方法中去,
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
//抽象方法
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
我们看到这个方法里面处理的逻辑,我们只需要看抽象方法那里了,也就是subscribeActual方法了,这个方法的参数是Observer,也就是我们订阅的时候传入的,因为是抽象方法,那么我们就要去他的实现类中去看看了,还记得在第一段代码中返回的是什么吗?是的,返回的就是Observable的实现类了,那么我们就去看看ObservaleCreate类中subscribeActual方法了。
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
在这个方法中,首先是创建一个CreateEmitter实例,然后该实例又当做参数传入了observer.onSubscribe(parent)方法中了,而我们记得在我们调用的时候实现observer匿名实现类的时候,他的参数是Disposable,那我们再看看CreateEmitter类,
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);
} finally {
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
...
}
发现该类实现既实现了ObservableEmitter接口,又实现了Disposable接口,发现里面很多我们常见的方法调用,现在接着往下走,source.subscribe方法,将CreateEmitter实例传入,这不正好就呼应了我们在使用的方式了么,发送消息用ObservableEmitter的onNext等方法,然后再看看CreateEmitter的onNext方法,发现里面调用的就是Observer的onNext方法,而这个Observer就是我们在使用的时候创建的那个匿名类了。
到此处,Create操作符的流程也就走通了,而这也是所有操作符中我认为最简单最直接的一个操作符了。
相信看到这里大家对RxJava应该有一个很深的印象了,那就是不停的订阅,然后通过接口来回调。而在使用中,我们也可以使用这种回调再次封装。比如说,我们在使用中很多时候都是结合Retrofit的来使用的,那么这个时候肯定就涉及到网络中各种请求的数据以及请求错误等等,我们不可能在每次请求结束都要对onNext,onError等方法进行重写,因为很多时候这些数据与错误结果是都类似的,那么这个时候我们就可以像这样,
public abstract class BaseObserver<T> extends ResourceObserver<ResultModel<T>> {
private static final String TAG = "BaseObserver";
@Override
public void onNext(ResultModel<T> value) {
if (!NetWork.isConnected(RLApplication.getInstance())) {
ToastUtil.warning(RLApplication.getInstance(),"网络故障,请检查网络连接是否正常");
onFinish();
return;
}
Log.d(TAG, "onNext - result -> " + value.toString());
T t = value.getData();
onSuccess(t);
}
/**
* 处理框架错误(包括okhttp的网络错误,转换错误,解析异常)
*
* @param e
*/
@Override
public void onError(Throwable e) {
Log.e(TAG, "error:" + e.toString());
e.printStackTrace();
if (e instanceof ResponseException) {
/** token 失效 code为2000,跳转到登录页面 */
if ("2000".equals(((ResponseException) e).getCode())) {
//退出登录,跳转到登录页面
AppManager.startLoginActivity();
}
onFailure(((ResponseException) e));
} else {
onFailure(new Exception(e));
}
onFinish();
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
onFinish();
}
/**
* 请求成功
*
* @param t
*/
protected abstract void onSuccess(T t);
/**
* 请求失败
*
* @param ex
*/
protected void onFailure(Exception ex) {
ToastUtil.error(RLApplication.getInstance(),ex.getMessage());
}
/**
* 请求结束,onError(),onComplete()之后都会调用,常用于关闭Dialog
*/
protected void onFinish() {
}
}
对其进行一个二次封装,这样的话,我们每次请求完毕只需要重写onSuccess与一个onFailure方法了,而这不也使我们以前一直用网络框架请求最后重写的方法吗,而且在这一过程中,我们还可以在onError方法中对某一些异常或者错误进行统一的处理,这样不是更加方便吗。
以上就是对Create操作符的核心原理的一个梳理,希望可以帮到大家,有什么问题或者建议也希望大家可以指正,谢谢!!!