上一篇文章分析了okhttp的源码,因为一个网络请求框架一般都是使用rxjava+okhttp+retrofit进行封装,所以现在对rxjava的源码进行解析。
众所周知,rxjava是使用的观察者的模式,观察者模式是一个使用率非常高的模式,这个模式的一个重要的作用就是解耦,将被观察者和观察者解耦,使得他们之间的依赖性更小,甚至毫无依赖。
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有的依赖于他的对象都会得到通知并被自动更新。
在分析rxjava前,先对Android中的观察者模式做一个简单的分析,对观察者模式有一个简单的了解。
下面我们来简单模拟下程序员订阅博文的发布---订阅过程。
一、程序员是观察者
/**
* 程序员是观察者
*/
public class Coder implements Observer {
private String name;
public Coder(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
Log.e("TAG","hi,"+name+"你观察的方法(订阅)更新啦"+",更新内容:"+arg);
}
@Override
public String toString() {
return "Coder{" +
"name='" + name + '\'' +
'}';
}
}
二、订阅的博文网站是被观察者
/**
* 这个类代表的是订阅的博文网站,这个是被观察的对象,当它有更新的使用所有的观察者(这里是程序员)都会接收到相应的消息
*/
public class DevTech extends Observable {
void postNewPublic(String context){
setChanged();
notifyObservers(context);
}
}
三、测试代码
在Android中测试的话,定义一个按钮进行触发,代码如下
DevTech devTech=new DevTech();
Coder coder=new Coder("程序员1");
Coder coder2=new Coder("程序员2");
Coder coder3=new Coder("程序员3");
Coder coder4=new Coder("程序员4");
devTech.addObserver(coder);
devTech.addObserver(coder2);
devTech.addObserver(coder3);
devTech.addObserver(coder4);
devTech.postNewPublic("我是你观察的博文,给你发送更新啦");
输出结果:
可以看到所有的订阅了博文的用户都接收到了消息,一对多的订阅----发布系统就完成了。
Observer和Observable是JDK中的内置类型,可见观察者是非常重要的,这里的Observer是抽象的观察者角色,Coder扮演的是具体的观察者的角色,Observable对应的是抽象主题角色,DevTech则是具体的主题角色。Coder是具体的观察者,他们订阅了DevTech这个具体的可观察对象,当DevTech进行更新时,会遍历所有的观察者(这里是coder),然后给这些观察者发布一个更新的消息,即调用Coder中的update方法,这样就达到了一对多的通知功能,在这个过程中,通知系统都是依赖Observer和Observable这些抽象类,因此,对于Coder和DevTech来说,完全没有耦合,保证了系统的灵活性,可拓展性。
在Android的源码中也使用到了观察者模式,比如我们经常使用的recycleview中的adapter,这里也是使用了观察者的模式进行数据的更新,还有广播等,这里就不介绍了。
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("发送消息");
emitter.onNext("发送消息1");
emitter.onNext("发送消息2");
emitter.onComplete();
}
});
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(mStringObserver);
Observer mStringObserver = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe");
}
@Override
public void onNext(String s) {
Log.e("TAG", s);
Log.e("TAG", "onNext");
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "onError");
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete");
}
};
或者也可以一步到位:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("发送消息");
emitter.onNext("发送消息1");
emitter.onNext("发送消息2");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe");
}
@Override
public void onNext(String s) {
Log.e("TAG", s);
Log.e("TAG", "onNext");
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "onError");
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete");
}
});
输出结果:
创建Observable(被观察者)
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("发送消息");
emitter.onNext("发送消息1");
emitter.onNext("发送消息2");
emitter.onComplete();
}
});
源码:
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Observable create(ObservableOnSubscribe source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}
public static T requireNonNull(T object, String message) {
if (object == null) {
throw new NullPointerException(message);
}
return object;
}
/**
* Calls the associated hook function.
* @param the value type
* @param source the hook's input value
* @return the value returned by the hook
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static Observable onAssembly(@NonNull Observable source) {
Function super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
class ObservableCreate extends Observable
abstract class Observable implements ObservableSource
从源码中,我们可以看到,Observable对象调用了 create(…) 方法返回的是一个 observable 对象,其实最终返回的是 ObservableCreate.
RxJavaPlugins.onAssembly 只是相当于 hook 而已。
创建Observer(观察者)
Observer mStringObserver = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe");
}
@Override
public void onNext(String s) {
Log.e("TAG", s);
Log.e("TAG", "onNext");
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "onError");
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete");
}
};
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(mStringObserver);
源码分析:
abstract class Observable implements ObservableSource
在Observable类中可以看到Observable实现了ObservableSource接口,重写了ObservableSource接口中的subscribe()方法。
@SchedulerSupport(SchedulerSupport.NONE)
@Override
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(…),该方法是个抽象方法,会调用实现类中的方法。
protected abstract void subscribeActual(Observer super T> observer);
实现类ObservableCreate中的方法:
@Override
protected void subscribeActual(Observer super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
最终会调用source.subscribe(parent);方法,source是在创建Observable时传的ObservableOnSubscribe对象,下面看看ObservableOnSubscribe类:
public interface ObservableOnSubscribe {
/**
* Called for each Observer that subscribes.
* @param emitter the safe emitter instance, never null
* @throws Exception on error
*/
void subscribe(@NonNull ObservableEmitter emitter) throws Exception;
}
所以最终会回调subscribe()方法。
然后在subscribe(ObservableEmitter
所以,在下面的subscribe()方法进行了数据的发送。
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("发送消息");
emitter.onNext("发送消息1");
emitter.onNext("发送消息2");
emitter.onComplete();
}
});
public interface ObservableEmitter extends Emitter {
void setCancellable(@Nullable Cancellable c);
boolean isDisposed();
@NonNull
ObservableEmitter serialize();
boolean tryOnError(@NonNull Throwable t);
}
而CreateEmitter是ObservableEmitter的实现类,所最终会调用CreateEmitter类中的方法进行消息的处理。
static final class CreateEmitter
extends AtomicReference
implements ObservableEmitter, 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();
}
}
}
@Override
public void setDisposable(Disposable d) {
DisposableHelper.set(this, d);
}
@Override
public void setCancellable(Cancellable c) {
setDisposable(new CancellableDisposable(c));
}
@Override
public ObservableEmitter serialize() {
return new SerializedEmitter(this);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
@Override
public String toString() {
return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
}
}
下面我们继续分析,我们只有看onNext()方法。
@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);
}
}
从上面方法中可以看出,如果没有被disposed ,则会调用 observer.onNext(t) 方法,observer 是最终的订阅者,将数据传个订阅者。这里将observable 与 observer 联系起来。
Observer mStringObserver = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe");
}
@Override
public void onNext(String s) {
Log.e("TAG", s);
Log.e("TAG", "onNext");
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "onError");
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete");
}
};
所以,最终所以订阅了该对象的订阅者都会接受到消息。
在分析上面的代码中,使用到了
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).subscribe(mStringObserver);
这里就进行了进程的调度操作。
Schedulers:调度器
subscribeOn(Schedulers.io()),这里将数据的发射放在 IO 线程中。
如果需要再Android中的UI使用到该数据,则需要更新UI,我们都知道更新UI是需要再Android的主线程中的,所以如果需要更新Android的UI,就需要把现场调度到Android中的主线程,RxJava没有提供调度到Android中主线程的方法,所以我们需要一个方法进行调度,在RxAndroid中就提供了一个方法,可以把线程调度到Android的主线程,然后进行UI的更新操作,项目看看RxAndroid中的进程调度方法:
public final class AndroidSchedulers {
private static final AtomicReference INSTANCE = new AtomicReference<>();
private final Scheduler mainThreadScheduler;
private static AndroidSchedulers getInstance() {
for (;;) {
AndroidSchedulers current = INSTANCE.get();
if (current != null) {
return current;
}
current = new AndroidSchedulers();
if (INSTANCE.compareAndSet(null, current)) {
return current;
}
}
}
private AndroidSchedulers() {
RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();
Scheduler main = hook.getMainThreadScheduler();
if (main != null) {
mainThreadScheduler = main;
} else {
mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());
}
}
/** A {@link Scheduler} which executes actions on the Android UI thread. */
public static Scheduler mainThread() {
return getInstance().mainThreadScheduler;
}
/** A {@link Scheduler} which executes actions on {@code looper}. */
public static Scheduler from(Looper looper) {
if (looper == null) throw new NullPointerException("looper == null");
return new LooperScheduler(looper);
}
/**
* Resets the current {@link AndroidSchedulers} instance.
* This will re-init the cached schedulers on the next usage,
* which can be useful in testing.
*/
@Experimental
public static void reset() {
INSTANCE.set(null);
}
}
从源码中,我们可以看到,AndroidSchedulers中有一个方法mainThread()方法中返回了一个Scheduler对象,而这个Scheduler对象就是Android的主线程。
把线程调度到主线程的方法:
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mStringObserver);
至此,就可以在Observer中的onNext()方法中获取想应的数据然后进行UI更新操作了。
附上解析demo:https://github.com/freakcsh/Rxjava