RxJava现在应用范围很广,可以和retrofit,okhttp结合实现网络请求,可以和GreenDao结合实现数据库功能,也能应用开发框架MVP,MVVM有很好的兼容性,这个也符合现在的大环境和很火热的概念,叫做生态。
RxJava火热的原因归结于4点:
1.流式操作
2.多元化的操作符
3.线程调度
4.背压
第二点不是本文的初衷,但是我浏览相关资料的时候发现一篇比较好的文章:RxJava2.x使用以及操作符详解
第四点发现一个作者写的好,就直接安利他的文章
Observable.create(
new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter)
throws Exception {}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer integer) {}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
RxJava抛开publisher创建的过程,遵循观察者模式publisher.subscribe(observer)
(01~07)装饰模式生成ObservableObserveOn对象
(08~22)观察者模式发布者订阅观察者
(23~28)发送消息
Rxjava存在3种类型的发布者:
(1)不切换线程的发布者ObservableCreate
(2)指定发布者运行在某一线程的发布者ObservableSubscribeOn
(3)指定观察者运行在某一线程的发布者ObservableObserveOn
这边作者借鉴了装饰模式的思路,将把类的核心职责和装饰功能区隔离,进行代码的解耦。
按照装饰顺序:
(1)将传入发布者匿名内部类,封装成核心类ObservableCreate
(2)将核心类ObservableCreate,装饰成发布者运行在IO线程的装饰类ObservableSubscribeOn
(3)将装饰类ObservableSubscribeOn,装饰成观察者运行在主线程的装饰类ObservableObserverOn
上述生成的ObservableObserverOn.subscribe(Observer) 生成对象按照下图中从上到下,subscribe是按照下图从下到上。
currentThread:调用者所在线程
(1)根据设定的线程(主线程)创建线程任务
(2)实例化ObserveOnObserver对象
(3)执行ObservableSubscribeOn.subscribe(ObserveOnObserver)
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
@Override
protected void subscribeActual(Observer observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
}
currentThread:调用者所在线程
(1)使用ObserveOnObserver创建SubscribeOnObserver对象
(2)回调给下游观察者onSubscribe
(3)线程调度使用指定发布者运行的线程(IO线程)执行
(4)currentThread= IO线程,执行ObservableCreate.subscribe(SubscribeOnObserver)
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
@Override
public void subscribeActual(final Observer observer) {
final SubscribeOnObserver parent = new SubscribeOnObserver(observer);
observer.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
@Override
public void run() {
System.err.println("Rxjava ObservableSubscribeOn Thread.currentThread() = " + Thread.currentThread().getId());
source.subscribe(parent);
}
}
currentThread:IO线程
(1)使用SubscribeOnObserver创建CreateEmitter发射器对象
(2)回调SubscribeOnObserver onSubscribe
(3)回调上游发布者方法subscribe
public final class ObservableCreate extends Observable {
@Override
protected void subscribeActual(Observer observer) {
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
}
currentThread:IO线程
(1)外部调用类获得发射器对象实例ObservableEmitter,执行OnNext方法
(2)调用SubscribeOnObserver.onNext(t)
public final class ObservableCreate extends Observable {
static final class CreateEmitter
extends AtomicReference
implements ObservableEmitter, Disposable {
@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);
}
}
}
}
currentThread:IO线程
(1)调用ObserveOnObserver.onNext(t)
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {
@Override
public void onNext(T t) {
downstream.onNext(t);
}
}
}
currentThread:IO线程
(1)使用线程调度切换到观察者指定的线程(主线程)
(2)currentThread=mainThread,回调下游观察者方法onNext
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
@Override
public void run() {
drainNormal();
}
void drainNormal() {
a.onNext(v);
}
}
}
这里就完成了发布者运行在IO线程,观察者在主线程的流程。接下来在看看线程调度。
结合EventBus线程操作发现,两者有很多相同点,从业务上讲都有线程调度,都有并发的风险,都有开辟大量线程的可能,从技术上讲两者都采用了线程池,清理缓存线程,超时机制,策略模式。技术方面最大的不同,EventBus采用锁来解决并发,RxJava使用是原子类。
(1)创建线程池运行并线程任务
(2)利用已有线程池运行线程任务
背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略。比较Observable,发现装饰模式生成发布者,策略模式线程调度没有变化。RxJava2.0提供了5种背压策略,区别在于发射器执行onNext时的逻辑处理
Flowable
.create(new FlowableOnSubscribe() {
@Override
public void subscribe(FlowableEmitter e) throws Exception {
for (int i = 1; i <= 130; i++) {
e.onNext(i);
}
}
}, BackpressureStrategy.MISSING/*ERROR*//*BUFFER*//*DROP*//*LATEST*/)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(new Subscriber() {
@Override
public void onSubscribe(Subscription s) {s.request(Long.MAX_VALUE);}
@Override
public void onNext(Integer integer) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("NoOverflowBaseAsyncEmitter onNext = " + integer);
}
@Override
public void onError(Throwable t) {
System.err.println("NoOverflowBaseAsyncEmitter onError = " + t);
}
@Override
public void onComplete() {
}
});
(1)MISSING
和ObservableEmitter没什么区别,直接把收到范形消息经过线程调度传给下游观察者。不过在这边方法结尾加了一个循环目的是为了保证当前可执行的消息数目要等于最大可发送的减去目前已经发送的。
static final class MissingEmitter extends BaseEmitter {
@Override
public void onNext(T t) {
if (isCancelled()) {
return;
}
if (t != null) {
downstream.onNext(t);
} else {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
for (;;) {
long r = get();
if (r == 0L || compareAndSet(r, r - 1)) {
return;
}
}
}
}
(2)ERROR
这边实现类似于倒计时的原理,ErrorAsyncEmitter是继承AtomicLong的,初始化绑定时调用request方法,设置初始值为128。每执行一次方法就调用 BackpressureHelper.produced设置当前还剩余可发送数量。如果为0,发送OnError消息抛出MissingBackpressureException异常。
static final class ErrorAsyncEmitter extends NoOverflowBaseAsyncEmitter {
@Override
public final void onNext(T t) {
if (isCancelled()) {
return;
}
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (get() != 0) {
System.err.println("NoOverflowBaseAsyncEmitter get() = " + get());
downstream.onNext(t);
BackpressureHelper.produced(this, 1);
} else {
System.err.println("NoOverflowBaseAsyncEmitter onOverflow");
onOverflow();
}
}
@Override
void onOverflow() {
onError(new MissingBackpressureException("create: could not emit value due to lack of requests"));
}
}
(3)DROP
这个发现和ERROR没什么区别,惟一的区别,计数器为0了,ERROR会给下游抛出onError异常,DROP就什么也不做
static final class DropAsyncEmitter extends NoOverflowBaseAsyncEmitter {
@Override
public final void onNext(T t) {
if (isCancelled()) {
return;
}
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (get() != 0) {
System.err.println("NoOverflowBaseAsyncEmitter get() = " + get());
downstream.onNext(t);
BackpressureHelper.produced(this, 1);
} else {
System.err.println("NoOverflowBaseAsyncEmitter onOverflow");
onOverflow();
}
}
@Override
void onOverflow() {
}
}
(4)LATEST
这个策略很有意思,就像你有一张额度为128的信用卡,但是你保持一笔账单消费1块钱,直到花了130。透支了2块钱。然后你收到账单了,累计账单达到96选择分期还款96。然后银行到账你的还款了,然后你又有额度了,你就可以接着去花了。这边选择这个策略前128个会保证正常返回,中间的就不能保证了,要看下游什么时候调用upstream.request(e),但是会保证最后一条数据返回给你。
这边和ERROR一样倒计时128,为0时就不再执行while循环任务。
public final class FlowableCreate extends Flowable {
static final class LatestAsyncEmitter extends BaseEmitter {
@Override
public void onNext(T t) {
if (done || isCancelled()) {
return;
}
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
queue.set(t);
drain();
}
void drain() {
if (wip.getAndIncrement() != 0) {
return;
}
int missed = 1;
final Subscriber a = downstream;
final AtomicReference q = queue;
for (;;) {
long r = get();
long e = 0L;
while (e != r) {
...
}
}
}
}
}
}
发送计数,达到96就告诉上游LatestAsyncEmitter调用BackpressureHelper.add(this, n);将0修改成96。让drain的while循环可以接着执行。
public final class FlowableObserveOn extends AbstractFlowableWithUpstream {
static final class ObserveOnSubscriber extends BaseObserveOnSubscriber
implements FlowableSubscriber {
@Override
public final void onNext(T t) {
if (done) {
return;
}
if (sourceMode == ASYNC) {
trySchedule();
return;
}
if (!queue.offer(t)) {
upstream.cancel();
error = new MissingBackpressureException("Queue is full?!");
done = true;
}
trySchedule();
}
@Override
void runAsync() {
int missed = 1;
final Subscriber a = downstream;
final SimpleQueue q = queue;
long e = produced;
for (;;) {
long r = requested.get();
while (e != r) {
...
if (e == limit) {
if (r != Long.MAX_VALUE) {
r = requested.addAndGet(-e);
}
upstream.request(e);
e = 0L;
}
}
}
}
}
}
(5)BUFFER
这个策略是先将事件存入AtomicReferenceArray中。这个数组的长度是129中然后在从数组中取出来,返回给下游,这边的index和时事件都是存放原子类中,防止并发问题。
public final class FlowableCreate extends Flowable {
static final class BufferAsyncEmitter extends BaseEmitter {
@Override
public void onNext(T t) {
if (done || isCancelled()) {
return;
}
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
queue.offer(t);
drain();
}
void drain() {
...
final Subscriber a = downstream;
final SpscLinkedArrayQueue q = queue;
for (;;) {
long r = get();
long e = 0L;
while (e != r) {
boolean d = done;
T o = q.poll();
...
boolean empty = o == null;
if (empty) {
break;
}
a.onNext(o);
e++;
}
...
}
}
}
}
很多人说用这个数组是无限大的可以一直往里面存,会导致oom。但是我看源码发现这个数组长度是129,不会是无限大的。所以我怀疑他们说的不对,或者源码更新了。但是这么说的人太多了,我只能根据我看的认为这个不会导致oom。
如果插入的index小于127,那么直接插入到数组中。
如果大于126,先利用与运算得出当前index与127的偏移量,然后去找当前索引是否含有值,发送完事件给下游之后会将当前index对应的事件置为null。所以可以继续往下存。
public final class SpscLinkedArrayQueue implements SimplePlainQueue {
@Override
public boolean offer(final T e) {
if (null == e) {
throw new NullPointerException("Null is not a valid element");
}
// local load of field to avoid repeated loads after volatile reads
final AtomicReferenceArray