RxjavaPlugins也是Rxjava源码的重要组成部分,Rxjava中几乎任何一个方法中都有RxjavaPlugins出现
RxjavaPlugins的主要作用就是Hook
普通Hook的方式是利用反射和动态代理替换某个类的成员变量;
而Rxjava提供了RxjavaPlugins这个工具类,用插桩的方式,通过Function替换方法的参数;
RxJavaPlugins:
public final class RxJavaPlugins {
//以Handler命名的Fuction替换的是线程调度器,这里只列举IO的,其他还有Computation等
static volatile Function<? super Callable<Scheduler>, ? extends Scheduler> onInitIoHandler;
static volatile Function<? super Scheduler, ? extends Scheduler> onIoHandler;
//以Assembly命名的Function替换掉的是Observable,还有其他还有Maybe,Single等
static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;
//以Subscribe命名的BiFunction替换掉的是Observer,还有其他还有Maybe,Single等
static volatile BiFunction<? super Observable, ? super Observer, ? extends Observer> onObservableSubscribe;
//上面的每个静态变量都对应一个静态方法,来为其赋值
public static void setOnObservableAssembly(Function<? super Observable, ? extends Observable> onObservableAssembly) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
RxJavaPlugins.onObservableAssembly = onObservableAssembly;
}
}
可以发现RxJavaPlugins可以替换三种对象,分别是Scheduler
,Observable
和Observer
,但是其中没有发现替换主线程Scheduler的方法,因为Java中没有主线程的概念,所以替换主线程的方法在RxAndroidPlugins中:
RxAndroidPlugins:
public final class RxAndroidPlugins {
//RxAndroidPlugins非常简洁,只提供了替换主线程Scheduler的方法
private static volatile Function<Callable<Scheduler>, Scheduler> onInitMainThreadHandler;
private static volatile Function<Scheduler, Scheduler> onMainThreadHandler;
public static void setInitMainThreadSchedulerHandler(Function<Callable<Scheduler>, Scheduler> handler) {
onInitMainThreadHandler = handler;
}
public static void setMainThreadSchedulerHandler(Function<Scheduler, Scheduler> handler) {
onMainThreadHandler = handler;
}
}
以io线程调度器为例:
Observable.just("Hello").subscribeOn(Schedulers.io())
public final class Schedulers {
static final Scheduler IO;
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
}
public final class RxJavaPlugins {
static volatile Function<? super Scheduler, ? extends Scheduler> onIoHandler;
//如果函数onIoHandler为空,就不做变换,直接使用defaultScheduler
//如果函数onIoHandler不为空,就用onIoHandler对defaultScheduler进行变换,返回一个新的调度器
public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
Function<? super Scheduler, ? extends Scheduler> f = onIoHandler;
if (f == null) {
return defaultScheduler;
}
return apply(f, defaultScheduler);
}
}
使用RxJavaPlugins去Hook线程调度器:
RxJavaPlugins.setIoSchedulerHandler(scheduler -> Schedulers.trampoline());
RxJavaPlugins.setComputationSchedulerHandler(scheduler -> Schedulers.trampoline());
RxAndroidPlugins.setInitMainThreadSchedulerHandler(scheduler -> Schedulers.trampoline());
Hook线程调度器的作用之一就是可以对Rxjava异步函数进行单元测试
普通的Observable:
public final void subscribe(Observer<? super T> observer) {
//用RxJavaPlugins对原始observer做变换
observer = RxJavaPlugins.onSubscribe(this, observer);
subscribeActual(observer);
}
RxJavaPlugins:
public final class RxJavaPlugins {
static volatile BiFunction<? super Observable, ? super Observer, ? extends Observer> onObservableSubscribe;
public static <T> Observer<? super T> onSubscribe(Observable<T> source, Observer<? super T> observer) {
BiFunction<? super Observable, ? super Observer, ? extends Observer> f = onObservableSubscribe;
if (f != null) {
return f.apply(source, observer);;
}
return observer;
}
}
Hook Observer例:
public void fun() {
RxJavaPlugins.setOnObservableSubscribe(((observable, observer) ->
new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e("Tag", "onSubscribe");
observer.onSubscribe(d);
}
@Override
public void onNext(Object o) {
Log.e("Tag", "onNext");
observer.onNext(o);
}
@Override
public void onError(Throwable e) {
Log.e("Tag", "onError");
observer.onError(e);
}
@Override
public void onComplete() {
Log.e("Tag", "onComplete");
observer.onComplete();
}
}));
Observable.just("Hello").subscribe() //打印了onSubscribe,onNext,onComplete三句Log
}
从此以后,所有的Observer对应的onNext等方法执行之前都会打印相应的Log,直到将RxJavaPlugins重置;
另外,如果Observable经过一些变换,每条Log会多次打印:
//打印onSubscribe,onSubscribe,onNext,onNext,onComplete,onComplete
Observable.just("Hello").map(s -> s+"?").subscribe()
Hook Observer:
Observer targetObserver = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e("Tag", "onSubscribe");
}
@Override
public void onNext(Object o) {
Log.e("Tag", "onNext");
}
@Override
public void onError(Throwable e) {
Log.e("Tag", "onError");
}
@Override
public void onComplete() {
Log.e("Tag", "onComplete");
}
};
RxJavaPlugins.setOnObservableSubscribe((observable, observer) -> targetObserver);
这样可以把所有Observable的订阅者都替换成targetObserver
几乎所有的Observable创建符都会出现RxJavaPlugins.onAssembly
方法,例如:
//create
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
//just
public static <T> Observable<T> just(T item) {
ObjectHelper.requireNonNull(item, "The item is null");
return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}
正常情况下,RxJavaPlugins实际什么都没有做,实际的Observable实际就是ObservableCreate和ObservableJust
public final class RxJavaPlugins {
static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;
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;
}
}
我们同样可以在所有创建Observable的时候打印一句Log:
RxJavaPlugins.setOnObservableAssembly(observable -> {
Log.e("Tag", "OnObservableCreate");
return observable;
});
Observable.just("Hello"); //只要有Observable创建就会打印Log
和Observer有类似的问题,就是如果涉及到一些变换,都会打印多条Log:
Observable.just("Hello").map(s -> s + "?"); //打印了两句Log
Hook Observable:
Observable targetObservable = Observable.just("Hook");
RxJavaPlugins.reset();
RxJavaPlugins.setOnObservableAssembly(o -> targetObservable);
Observable.just("Hello"); //这里实际创建了一个发送Hook的Observable