3-1、Rxjava-创建操作符create源码分析

717 阅读5分钟

基本使用

让我们回顾一下create操作符创建一个基础使用方式

Observable.create(new ObservableOnSubscribe<Integer>() {
    //此时是接口回调的响应方, 类似Android中的View.setOnClickListener
    @Override
    public void subscribe(@NonNull ObservableEmitter<Integer> emitter) {
        if (!emitter.isDisposed()) {
            //这里也是接口回调, 不过emitter是触发方
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
        }
        emitter.onComplete();
    } 
}).subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "开始采用subscribe连接");
    }

    @Override
    public void onNext(Integer value) {
        Log.d(TAG, "接收到了事件" + value);
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "对Error事件作出响应");
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "对Complete事件作出响应");
    }
});

>>>>>>
开始采用subscribe连接
接收到了事件1
接收到了事件2
接收到了事件3
对Complete事件作出响应

按步骤划分为三步:

  1. Observable 的 create方法创建了一个Observable对象
  2. new Observer 创建一个Observer对象
  3. Observable 的实例调用 subscribe 方法订阅 Observer实例

让我们来看一下源码

1. Observable的创建是调用静态方法 create , 传入参数是 ObservableOnSubscribe, 返回的类型是Observable, 具体是 new ObservableCreate(source)生成的对象。

代码1.1
** Observable抽象类中 **

/**
 * 创建操作符
 * @param source: ObservableOnSubscribe的实例对象
 */
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    // 1. 判空处理
    ObjectHelper.requireNonNull(source, "source is null");
    // 2. 返回的是其参数本身 new ObservableCreate<T>(source)
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}

//该处可以看出:
1. ObservableOnSubscribe和创建Observable有关
2. ObservableCreate是Observable的子类
代码1.2
** RxJavaPlugins类中 **

/**
 * 工具类的方法
 */
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
    // 1. 此时的onObservableAssembly为null
    Function<? super Observable, ? extends Observable> f = onObservableAssembly;
    if (f != null) {
        return apply(f, source);
    }
    // 2. 返回source
    return source;
}

//该处可以看出:
1. onObservableAssembly 为null, 所以 RxJavaPlugins.onAssembly 返回的是它本身传入的参数
代码1.3
** ObservableOnSubscribe接口中 **

//ObservableOnSubscribe是一个接口, 用于给用户动态创建不同对象实例
public interface ObservableOnSubscribe<T> {

    //订阅后发射
    //何时调subscribe何时发射数据, 实质是接口回调
    void subscribe(@NonNull ObservableEmitter<T> emitter) throws Exception;
}

//该处可以推测出:
1. 用于创建发射数据
2. 接口回调, 当调用 subscribe 时触发

思考: 何时调用 subscribe ?
    ( ObservableCreate 的 subscribeActual 方法中调用 )
代码1.4
** ObservableEmitter接口中 **

//ObservableEmitter 也是一个接口, 它继承Emitter, 用于动态创建发射的对象实例
public interface ObservableEmitter<T> extends Emitter<T> {

    void setDisposable(@Nullable Disposable d);

    void setCancellable(@Nullable Cancellable c);

    boolean isDisposed();

    @NonNull
    ObservableEmitter<T> serialize();

    boolean tryOnError(@NonNull Throwable t);
}

** Emitter接口中 **

//三个基本发射状态
public interface Emitter<T> {

    void onNext(@NonNull T value);

    void onError(@NonNull Throwable error);

    void onComplete();
}

//该处可以推测出:
1. 用于发射事件onNext、onError、onComplete

2. Observer是一个接口, 用于接收响应信息。

代码2.1

public interface Observer<T> {

    void onSubscribe(@NonNull Disposable d);
  
    void onNext(@NonNull T t);
   
    void onError(@NonNull Throwable e);
  
    void onComplete();
}

//该处可以看出:
1. 可以看出观察者响应的事件类型

思考: 观察者和被观察者是何时订阅的?
    (CreateEmitter 中)

3. Observable对象调用subscribe方法订阅Observer, subscribe方法里有一个 subscribeActual 方法给子类去重写

所以我们要关注的是, Observable的子类是如何重写 subscribeActual 方法的

代码3.1
** Observable抽象类中 **
//Observable 是一个抽象类, ObservableCreate 是Observable的子类。

public final class ObservableCreate<T> extends Observable<T> {
    //详情见代码1.3
    //ObservableOnSubscribe是一个接口, 里面的方法参数ObservableEmitter用于发射数据
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    //subscribeActual方法是在观察者和被观察者订阅的时候才会触发
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        //创建一个AtomicReference原子对象,用于设置disposed状态和判断isDisposed
        //它既可以是ObservableEmitter的实例, 也可以是Disposable的实例
        //此处 ObservableEmitter 和 Observer 建立关联
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        //触发observer的回调方法onSubscribe
        observer.onSubscribe(parent);

        try {
            //在上一步 ObservableEmitter 和 Observer 已建立关联,此时ObservableOnSubscribe的对象调用其本身的subscribe方法,ObservableEmitter对象发射的数据,Observer才能接收
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            //发射数据时的异常直接走onError方法
            parent.onError(ex);
        }
    }

    //AtomicReference 原子引用类, 防止多线程操作出现的错误
    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {


        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }

        //重写ObservableEmitter的方法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
                observer.onNext(t);
            }
        }

        //重写ObservableEmitter的方法onError
        @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
                    observer.onError(t);
                } finally {
                    //最终断开连接
                    dispose();
                }
                return true;
            }
            return false;
        }

        //重写ObservableEmitter的方法
        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    //触发observer的回调方法onComplete
                    observer.onComplete();
                } finally {
                    //最终断开连接
                    dispose();
                }
            }
        }

        @Override
        public void setDisposable(Disposable d) {
            //DisposableHelper是单例
            DisposableHelper.set(this, d);
        }

        @Override
        public void setCancellable(Cancellable c) {
            setDisposable(new CancellableDisposable(c));
        }

        @Override
        public ObservableEmitter<T> serialize() {
            return new SerializedEmitter<T>(this);
        }

        @Override
        public void dispose() {
            //DisposableHelper是单例
            DisposableHelper.dispose(this);
        }

        @Override
        public boolean isDisposed() {
            //DisposableHelper是单例
            return DisposableHelper.isDisposed(get());
        }

        @Override
        public String toString() {
            return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
        }
    }

}
代码3.2

public enum DisposableHelper implements Disposable {
    //枚举单例, 用于是否要终止的标识
    DISPOSED
    ;

    //判断记录的终止标识是否是传入的Observer
    public static boolean isDisposed(Disposable d) {
        //比较内存地址
        return d == DISPOSED;
    }

    //
    public static boolean set(AtomicReference<Disposable> field, Disposable d) {
        for (;;) {
            Disposable current = field.get();
            if (current == DISPOSED) {
                if (d != null) {
                    d.dispose();
                }
                return false;
            }
            if (field.compareAndSet(current, d)) {
                if (current != null) {
                    current.dispose();
                }
                return true;
            }
        }
    }

    ******省略代码******

    //
    public static boolean dispose(AtomicReference<Disposable> field) {
        //1.current为当前Observer的Disposable的值, 第一次调用时current为null
        Disposable current = field.get();
        //2.终止标识
        Disposable d = DISPOSED;
        //3.两次不相同, 说明Observer未调用dispose
        if (current != d) {
            //4.讲终止标识的值设置给当前的Observer的Disposable,
            //并返回设置前的Observer的Disposable的值,
            //此时调用isDisposed(Disposable d)返回的就是true了
            current = field.getAndSet(d);
            if (current != d) {
                //第一次调用时会走到这里, 此时current==null, 返回true
                //current不为null时说明当前的Observer调用了多次dispose(), 
                //而如果多次调用了Disposable的值还不是DISPOSED, 
                //说明之前设置失效, 所以再次调用dispose()
                if (current != null) {
                    current.dispose();
                }
                return true;
            }
        }
        return false;
    }
    
    ******省略代码******
}

疑问:

  1. AtomicReference原子引用原理