1. 如何使用Rxjava
导入包
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.12'
创建被观察者:
//创建一个被观察者
Observable<Integer> observable= Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onComplete();
}
});
创建观察者
//创建一个观察者
Observer<Integer> observer=new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.d(TAG,"onNext:"+integer);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG,"onComplete:");
}
};
注册
//注册
observable.subscribe(observer);
然后在观察者中便拿到了上游发送的值
04-24 10:19:28.313 2497-2497/? D/MainActivity: onNext:1
04-24 10:19:28.313 2497-2497/? D/MainActivity: onNext:2
04-24 10:19:28.313 2497-2497/? D/MainActivity: onComplete:
到这里就完成了一个简单的RxJava的使用。
2. 线程切换
首先我们对观察者和被观察者所在的线程进行打印,看下各自分别所在线程。
04-24 10:26:58.079 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: observable:main
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:main
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:1
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:main
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:2
04-24 10:26:58.080 4500-4500/com.example.a2018_3_14.rxdemo D/MainActivity: onComplete:
通过日志可以看出来都是在主线程中操作。但是我们平常需要做耗时操作怎么办呢,那第一时间会想到创建一个线程就解决了,这样也是没毛病的,不过在使用Rxjava中,它已经帮我在这一块封装好了。
//注册
observable.subscribeOn(Schedulers.io())//将被观察者切换到io线程
.observeOn(AndroidSchedulers.mainThread())//再将observer所在的线程切换到主线程
.subscribe(observer);
04-24 10:44:08.514 8070-8137/com.example.a2018_3_14.rxdemo D/MainActivity: observable:RxCachedThreadScheduler-1
04-24 10:44:08.535 8070-8070/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:main
04-24 10:44:08.535 8070-8070/com.example.a2018_3_14.rxdemo D/MainActivity: onNext:1
通过打印的日志看出来确实在observable所在的线程被切换到了一个新的线程中,由于 .observeOn(AndroidSchedulers.mainThread())调用之后又将下游接受到的事件线程切换到了主线程。
subscribeOn用于对被观察者的线程进行切换,当多次切换时,只有第一次有效,observeOn用于对观察者进行线程切换,可以多次切换。
3. 线程调度器如何工作可以实现线程的切换
首先分析下面的这段代码,找到如何实现订阅:
//创建一个被观察者
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
Log.d(TAG, "observable:" + Thread.currentThread().getName());
emitter.onComplete();
}
});
//创建一个观察者
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext:" + Thread.currentThread().getName());
Log.d(TAG, "onNext:" + integer);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete:" + Thread.currentThread().getName());
Log.d(TAG, "onComplete:");
}
};
//注册
observable.subscribeOn(Schedulers.io())//将被观察者切换到io线程
.observeOn(AndroidSchedulers.mainThread())//将观察者切换到主线程
.(observer);
在create方法中的返回值中调用了onAssembly这个方法,就是返回了一个ObservableCreate对象,ObservableCreate是继承了Observable。
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");//判断空
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));//返回ObservableCreate对象
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
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;
}
然后看ObservableCreate这个类,在这个类中的subscribeActual有订阅的方法,这个方法是什么时候调的呢,是在Observable.subscribe()方法中,在subscrible中有这段代码 subscribeActual(observer);然而这个方法是一个抽象方法,而ObservableCreate就是它的实现类,ObservableCreate中的subscribeActual就是对应的实现方法。
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);//调用观察者的onSubscribe
try {
source.subscribe(parent);//调用ObservableOnSubscribe的subscribe
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
在subscribeActual方法内部,首先把observer用CreateEmitter封装了下,CreateEmitter是ObservableCreate的内部类,并且实现ObservableEmitter,当调用 emitter.onNext(1);时会调用CreateEmitter的onNext()方法,判断isDisposed()不为空,然后调用obser的onNext()方法,同理onError,onComplete一样
@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);
}
}
observeOn()内部线程切换
首先看observeOn()的方法内部是怎么实现的:
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
在OnAssembly这个方法中最终返回ObservableObserveOn对象,ObservableObserveOn实现了Observable。在ObservableObserveOn的构造方法中将线程调度类作为参数传入
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;
}
然后看ObservableObserveOn这个类的内部的subscribeActual这个方法中走的是else方法,createWorker在Scheduler 中是一个抽象方法,具体的实现在IoScheduler中,返回的是EventLoopWorker这个内部类,然后订阅。
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
final boolean delayError;
final int bufferSize;
public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source);
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
// 在源码中对TrampolineScheduler的解释Schedules work on the current thread but does not execute immediately. Work is put in a queue and executed after the current unit of work is completed.
//调度任务不会再当前线程立即执行,任务会被放在一个队列里面在当前任务的单元完成后执行。主要看else方法
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
然后接着看ObserveOnObserver这个内部类,ObserveOnObserver实现了Runnable,在内部的onNext方法中 调用了调度schedule()。
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();//调度方法
}
在schedule()方法中调用了EventLoopWorker的schedule方法,然后追到EventLoopWorker源码中看下做了什么,应该就能找到线程切换的具体实现。
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
在EventLoopWorker的schedule方法中调用了threadWorker的scheduleActual方法
@Override
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
}
在scheduleActual的方法中,把ObserveOnObserver放入到了线程池中,这样就完成了线程的切换。
@NonNull
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
Future<?> f;
try {
if (delayTime <= 0) {
f = executor.submit((Callable<Object>)sr);//线程池的方法
} else {
f = executor.schedule((Callable<Object>)sr, delayTime, unit);
}
sr.setFuture(f);
} catch (RejectedExecutionException ex) {
if (parent != null) {
parent.remove(sr);
}
RxJavaPlugins.onError(ex);
}
return sr;
}
然后最后看下ObserveOnObserver的run方法的实现,会执行drainNormal()方法,然后看下drainNormal()方法内部的实现。
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();//执行该方法,
}
}
在drainNormal内部调用observer的onNext()方法。该方法在io线程中执行
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
a.onNext(v);//调用OnNext方法
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
到这里就把observerOn的线程切换流程分析完了。subscribeOn()就不做具体的分析了。