基于RxJava 2.0+版本,对RxJava的订阅源码进行简单分析。
1. 使用实例
我们在使用RxJava2.0时,一般像下面这样使用。
//1.创建被观察者
val flowable = Flowable.create(object : FlowableOnSubscribe {
@Throws(Exception::class)
override fun subscribe(e: FlowableEmitter) {
e.onNext("Hello")
e.onNext("World")
e.onNext("!")
//注意在此调用onComplete方法结束事件的处理
e.onComplete()
}
}, BackpressureStrategy.BUFFER)
// 2.创建观察者
val subscriber = object : Subscriber {
override fun onSubscribe(s: Subscription) {
println("onSubscribe")
// 不调用方法,无法发送流。
s.request(Long.MAX_VALUE)
}
override fun onNext(s: String) {
println(s)
}
override fun onError(t: Throwable) {
t.printStackTrace()
}
override fun onComplete() {
println("onComplete")
}
}
// 3.订阅
flowable.subscribe(subscriber)
以上代码基于Kotlin实现,Java实现方式基本类似。
2. 源码分析
2.1 创建被观察者
//1.创建被观察者
val flowable = Flowable.create(object : FlowableOnSubscribe {
// 1. 方法在产生订阅关系后被调用
@Throws(Exception::class)
override fun subscribe(e: FlowableEmitter) {
// 使用发射器发送事件
e.onNext("Hello")
e.onNext("World")
e.onNext("!")
//注意在此调用onComplete方法结束事件的发送
e.onComplete()
}
}, BackpressureStrategy.BUFFER)
FlowableOnSubscribe
public interface FlowableOnSubscribe {
/**
* Called for each Subscriber that subscribes.
* @param emitter the safe emitter instance, never null
* @throws Exception on error
*/
void subscribe(@NonNull FlowableEmitter emitter) throws Exception;
}
FlowableOnSubscribe接口在发生调阅关系时被调用,用于控制处理、发送事件。
FlowableEmitter
事件发射器,可以调用其接口来发送事件。
public interface FlowableEmitter extends Emitter {
/**
* Sets a Disposable on this emitter; any previous Disposable
* or Cancellation will be disposed/cancelled.
* @param s the disposable, null is allowed
*/
void setDisposable(@Nullable Disposable s);
/**
* Sets a Cancellable on this emitter; any previous Disposable
* or Cancellation will be disposed/cancelled.
* @param c the cancellable resource, null is allowed
*/
void setCancellable(@Nullable Cancellable c);
/**
* The current outstanding request amount.
* This method is thread-safe.
* @return the current outstanding request amount
*/
long requested();
/**
* Returns true if the downstream cancelled the sequence or the
* emitter was terminated via {@link #onError(Throwable)}, {@link #onComplete} or a
* successful {@link #tryOnError(Throwable)}.
*
This method is thread-safe.
* @return true if the downstream cancelled the sequence or the emitter was terminated
*/
boolean isCancelled();
/**
* Ensures that calls to onNext, onError and onComplete are properly serialized.
* @return the serialized FlowableEmitter
*/
@NonNull
FlowableEmitter serialize();
/**
* Attempts to emit the specified {@code Throwable} error if the downstream
* hasn't cancelled the sequence or is otherwise terminated, returning false
* if the emission is not allowed to happen due to lifecycle restrictions.
*
* Unlike {@link #onError(Throwable)}, the {@code RxJavaPlugins.onError} is not called
* if the error could not be delivered.
* @param t the throwable error to signal if possible
* @return true if successful, false if the downstream is not able to accept further
* events
* @since 2.1.1 - experimental
*/
@Experimental
boolean tryOnError(@NonNull Throwable t);
}
Emitter
public interface Emitter {
/**
* Signal a normal value.
* @param value the value to signal, not null
*/
void onNext(@NonNull T value);
/**
* Signal a Throwable exception.
* @param error the Throwable to signal, not null
*/
void onError(@NonNull Throwable error);
/**
* Signal a completion.
*/
void onComplete();
}
这个才是真正发送数据的接口定义。
Flowable.Create
public static Flowable create(FlowableOnSubscribe source, BackpressureStrategy mode) {
ObjectHelper.requireNonNull(source, "source is null");
ObjectHelper.requireNonNull(mode, "mode is null");
return RxJavaPlugins.onAssembly(new FlowableCreate(source, mode));
}
根据FlowableOnSubscribe、背压策略构造并返回FlowableCreate实例。
RxJavaPlugins.onAssembly
public static Flowable onAssembly(@NonNull Flowable source) {
Function super Flowable, ? extends Flowable> f = onFlowableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
如果设置了相关的转换方法,则调用,否则返回传入的Flowable。
FlowableCreate-实际创建的对象
- FlowableCreate继承于Flowable。
- 会根据背压模式创建不同的发射器,用于订阅时的回调。
public final class FlowableCreate extends Flowable {
final FlowableOnSubscribe source;
final BackpressureStrategy backpressure;
public FlowableCreate(FlowableOnSubscribe source, BackpressureStrategy backpressure) {
this.source = source;
this.backpressure = backpressure;
}
@Override
public void subscribeActual(Subscriber super T> t) {
BaseEmitter emitter;
switch (backpressure) {
case MISSING: {
emitter = new MissingEmitter(t);
break;
}
case ERROR: {
emitter = new ErrorAsyncEmitter(t);
break;
}
case DROP: {
emitter = new DropAsyncEmitter(t);
break;
}
case LATEST: {
emitter = new LatestAsyncEmitter(t);
break;
}
default: {
emitter = new BufferAsyncEmitter(t, bufferSize());
break;
}
}
// 调用Subscriber的onSubscribe方法[onSubscribe(s: Subscription)]
// emitter实际上继承了Subscription
t.onSubscribe(emitter);
try {
// 调用FlowableOnSubscribe的subscribe方法[subscribe(e: FlowableEmitter)]
// emitter实际上继承了FlowableEmitter
source.subscribe(emitter);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
emitter.onError(ex);
}
}
}
2.2 创建观察者
// 定义观察者
val subscriber = object : Subscriber {
override fun onSubscribe(s: Subscription) {
println("onSubscribe")
// 不调用方法,无法发送流。
s.request(Long.MAX_VALUE)
}
override fun onNext(s: String) {
println(s)
}
override fun onError(t: Throwable) {
t.printStackTrace()
}
override fun onComplete() {
println("onComplete")
}
}
Subscriber
public interface Subscriber {
/**
* Invoked after calling {@link Publisher#subscribe(Subscriber)}.
*
* No data will start flowing until {@link Subscription#request(long)} is invoked.
*
* It is the responsibility of this {@link Subscriber} instance to call {@link Subscription#request(long)} whenever more data is wanted.
*
* The {@link Publisher} will send notifications only in response to {@link Subscription#request(long)}.
*
* @param s
* {@link Subscription} that allows requesting data via {@link Subscription#request(long)}
*/
public void onSubscribe(Subscription s);
/**
* Data notification sent by the {@link Publisher} in response to requests to {@link Subscription#request(long)}.
*
* @param t the element signaled
*/
public void onNext(T t);
/**
* Failed terminal state.
*
* No further events will be sent even if {@link Subscription#request(long)} is invoked again.
*
* @param t the throwable signaled
*/
public void onError(Throwable t);
/**
* Successful terminal state.
*
* No further events will be sent even if {@link Subscription#request(long)} is invoked again.
*/
public void onComplete();
}
该接口主要是定义了事件处理方法,特别需要注意的几点:
onSubscribe在发生订阅关系时首先被调用;
除非在该方法中调用了Subscription.request方法,否则数据流不会发送;也可以在该方法中调用Subscription.cancel取消数据流的发送。onError与onComplete方法互斥。
onNext接收事件并处理。
2.3 订阅
// 3.订阅
flowable.subscribe(subscriber)
Flowable.subscribe(Subscriber super T> s)
public final void subscribe(Subscriber super T> s) {
// 我们只实现了Subscriber接口,s为FlowableSubscriber实例
if (s instanceof FlowableSubscriber) {
// 实际调用的是subscribe(FlowableSubscriber super T> s)
subscribe((FlowableSubscriber super T>)s);
} else {
ObjectHelper.requireNonNull(s, "s is null");
subscribe(new StrictSubscriber(s));
}
}
FlowableSubscriber
public interface FlowableSubscriber extends Subscriber {
/**
* Implementors of this method should make sure everything that needs
* to be visible in {@link #onNext(Object)} is established before
* calling {@link Subscription#request(long)}. In practice this means
* no initialization should happen after the {@code request()} call and
* additional behavior is thread safe in respect to {@code onNext}.
*
* {@inheritDoc}
*/
@Override
void onSubscribe(@NonNull Subscription s);
}
其实FlowableSubscriber与Subscriber的定义相同。
Flowable.subscribe(FlowableSubscriber super T> s)
public final void subscribe(FlowableSubscriber super T> s) {
ObjectHelper.requireNonNull(s, "s is null");
try {
// 附加操作
Subscriber super T> z = RxJavaPlugins.onSubscribe(this, s);
ObjectHelper.requireNonNull(z, "Plugin returned null Subscriber");
// 实际的实现在这里
subscribeActual(z);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Subscription 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;
}
}
Flowable.subscribeActual
protected abstract void subscribeActual(Subscriber super T> s)
这个方法为抽象方法,那么它的实际实现在哪里呢?答案就是我们在创建Flowable时分析的FlowableCreate。
FlowableCreate.subscribeActual
public final class FlowableCreate extends Flowable {
// 1. 创建Flowable对象时传入的FlowableOnSubscribe实例
final FlowableOnSubscribe source;
// 1. 创建Flowable对象时传入的背压策略
final BackpressureStrategy backpressure;
public FlowableCreate(FlowableOnSubscribe source, BackpressureStrategy backpressure) {
this.source = source;
this.backpressure = backpressure;
}
@Override
public void subscribeActual(Subscriber super T> t) {
BaseEmitter emitter;
// 根据不同的背压策略,创建不同的发射器
switch (backpressure) {
case MISSING: {
emitter = new MissingEmitter(t);
break;
}
case ERROR: {
emitter = new ErrorAsyncEmitter(t);
break;
}
case DROP: {
emitter = new DropAsyncEmitter(t);
break;
}
case LATEST: {
emitter = new LatestAsyncEmitter(t);
break;
}
default: {
// 我们创建的是这个
emitter = new BufferAsyncEmitter(t, bufferSize());
break;
}
}
// 1. 首先回调Subscriber的onSubscribe方法
t.onSubscribe(emitter);
try {
// 2.回调FlowableOnSubscribe的subscribe方法
// 我们一般在subscribe方法中发送数据
source.subscribe(emitter);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
// 发生异常,则直接回调onError接口
emitter.onError(ex);
}
}
}
BufferAsyncEmitter
BufferAsyncEmitter系FlowableCreate的静态内部类,Emitter设计为对外透明,用户只需设置背压策略即可。
static final class BufferAsyncEmitter extends BaseEmitter {
private static final long serialVersionUID = 2427151001689639875L;
final SpscLinkedArrayQueue queue;
Throwable error;
volatile boolean done;
final AtomicInteger wip;
// 1. actual实际的订阅者。
// 2. capacityHint默认值为128。
BufferAsyncEmitter(Subscriber super T> actual, int capacityHint) {
super(actual);
this.queue = new SpscLinkedArrayQueue(capacityHint);
this.wip = new AtomicInteger();
}
// 我们在Flowable的subscribe方法,调用此接口来发送事件。
@Override
public void onNext(T t) {
// 1. 当我们在Flowable.subscribe中调用onComplete方法后,done为true,事件不再发送
// 2. 当我们在Flowable.subscribe调用cancel方法后,isCancelled返回true
// 3. 当我们在Subscriber的onSubscribe方法调用Subsription.cancel方法后,isCancelled返回true
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();
}
@Override
public boolean tryOnError(Throwable e) {
if (done || isCancelled()) {
return false;
}
if (e == null) {
e = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
error = e;
done = true;
drain();
return true;
}
// 我们在Flowable的subscribe方法调用该方法来结束事件发送
@Override
public void onComplete() {
done = true;
drain();
}
// 调用request方法后,该方法会被调用
@Override
void onRequested() {
drain();
}
@Override
void onUnsubscribed() {
if (wip.getAndIncrement() == 0) {
queue.clear();
}
}
void drain() {
// 当前正在进行事件分发,因为在onNext中已经将事件加入队列,直接返回
if (wip.getAndIncrement() != 0) {
return;
}
int missed = 1;
final Subscriber super T> a = actual;
final SpscLinkedArrayQueue q = queue;
// 进入循环进行事件分发
for (;;) {
// 1. 未调用request方法,r==0
// 2. request方法,r==n
long r = get();
long e = 0L;
// 只有调用了request方法,e!=r
while (e != r) {
// 如果已经被取消,清空队列,直接返回
if (isCancelled()) {
q.clear();
return;
}
boolean d = done;
T o = q.poll();
boolean empty = o == null;
// 判断事件正常结束or异常
if (d && empty) {
Throwable ex = error;
if (ex != null) {
error(ex);
} else {
complete();
}
return;
}
if (empty) {
break;
}
// 事件不为空,分发事件
a.onNext(o);
e++;
}
// 1.如果未调用request方法,e==r==0
// 2. 调用了request方法,则执行上面的分发代码,直到e==r
if (e == r) {
if (isCancelled()) {
q.clear();
return;
}
boolean d = done;
boolean empty = q.isEmpty();
if (d && empty) {
Throwable ex = error;
if (ex != null) {
error(ex);
} else {
complete();
}
return;
}
}
if (e != 0) {
BackpressureHelper.produced(this, e);
}
// 未调用request方法,missed==0
missed = wip.addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
}
BaseEmitter
由上面的分析,我们知道BufferAsyncEmitter继承BufferAsyncEmitter。
在示例中,我们说明了只有在Subscriber.onSubscribe方法中调用Subscription的request方法,事件才能发送。
示例代码:
val subsrciber = object : Subscriber {
//由订阅时的代码分析可知, s此时实际上为BufferAsyncEmitter示例
override fun onSubscribe(s: Subscription) {
println("onSubscribe")
// 不调用方法,无法发送流。
s.request(Long.MAX_VALUE)
}
}
BaseEmitter
abstract static class BaseEmitter
extends AtomicLong
implements FlowableEmitter, Subscription {
BaseEmitter(Subscriber super T> actual) {
this.actual = actual;
this.serial = new SequentialDisposable();
}
@Override
public void onComplete() {
complete();
}
protected void complete() {
if (isCancelled()) {
return;
}
try {
actual.onComplete();
} finally {
serial.dispose();
}
}
@Override
public final void request(long n) {
if (SubscriptionHelper.validate(n)) {
// 此处设置了AtomicLong为n
BackpressureHelper.add(this, n);
onRequested();
}
}
// 省略......
}
订阅的核心是FlowableCreate和BaseEmitter这两个类,实现上还是比较清晰明了的。
3. 总结
本章只是简单的分析了RxJava2.0的订阅源码,RxJava的使用和实现远比此复杂,在此抛砖引玉,希望大家能活用、善用RxJava来提高工作效率,早日解放自己。