fromArray基本使用
fromArray用來創建一個Observable對象,可以將一個數組轉化爲可被觀察的序列並且將它的數據逐個發射。
fromArray與just相似,都可以用來發射單個或一組數據,但是區別是當fromArray發射一組數據到觀察序列中來時,它會先進行遍歷,然後再逐個發射。而just發射一組數據時,會把它當成一個整體,一次性發射。字面意思難以理解,我們用代碼說明:
Integer[] items = { 0, 1, 2, 3, 4, 5 };
Observable.fromArray(items).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
println("onNext : fromArray : " + integer + "\n");
}
});
Observable.just(items).subscribe(new Consumer<Integer[]>() {
@Override
public void accept(Integer[] integers) throws Exception {
for (int i: integers) {
println("onNext : just : " + i + "\n");
}
}
});
輸出結果:
onNext : fromArray : 0
onNext : fromArray : 1
onNext : fromArray : 2
onNext : fromArray : 3
onNext : fromArray : 4
onNext : fromArray : 5
onNext : just : 0
onNext : just : 1
onNext : just : 2
onNext : just : 3
onNext : just : 4
onNext : just : 5
上面輸出結果是不一樣的,使用fromArray時,接收的數據是逐個打印出來,而使用just時,直接接收的是一個數組。所以如上面所說fromArray接收的數據源是逐個發射的,而just是將數據作爲一個完整的對象一次性發射的。
下面我們將繼續從源碼的角度進行分析:
老規矩我們還是從fromArray方法中着手分析:
Observable#fromArray
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> fromArray(T... items) {
ObjectHelper.requireNonNull(items, "items is null");
if (items.length == 0) {
return empty();
} else
if (items.length == 1) {
return just(items[0]);
}
return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));
}
fromArray方法接收的是一個可變參數,該參數又作爲創建ObservableFromArray對象的參數。最後返回的是ObservableFromArray對象,作爲Observable的具體實現類。
然後開始訂閱觀察者對象,這裏我使用Consumer作爲觀察者。繼續查看subscribe方法:
Observable#subscribe
......
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete, Consumer<? super Disposable> onSubscribe) {
ObjectHelper.requireNonNull(onNext, "onNext is null");
ObjectHelper.requireNonNull(onError, "onError is null");
ObjectHelper.requireNonNull(onComplete, "onComplete is null");
ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");
LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);
subscribe(ls);
return ls;
}
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable 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;
}
}
這裏其實和just操作符調用的邏輯一樣,都是重載的subscribe方法,最後執行的是接收四個參數的subscribe方法,如上。這裏的創建LambdaObserver對象,不再做重複說明。
subscribeActual其實調用的是Observable實現類中的方法,也就是ObservableFromArray中的方法。我們直接進入該類中查看:
ObservableFromArray
public final class ObservableFromArray<T> extends Observable<T> {
final T[] array;
public ObservableFromArray(T[] array) {
this.array = array;
}
@Override
public void subscribeActual(Observer<? super T> s) {
FromArrayDisposable<T> d = new FromArrayDisposable<T>(s, array);
s.onSubscribe(d);
if (d.fusionMode) {
return;
}
d.run();
}
......
}
subscribeActual中,創建了一個FromArrayDisposable類對象,執行了Observer中的onSubscribe方法,也就是LambdaObserver中的onSubscribe方法。我們在進入這個方法中看一下:
LambdaObserver#onSubscribe
public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete,
Consumer<? super Disposable> onSubscribe) {
super();
this.onNext = onNext;
this.onError = onError;
this.onComplete = onComplete;
this.onSubscribe = onSubscribe;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.setOnce(this, s)) {
try {
onSubscribe.accept(this);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
onError(ex);
}
}
}
通過第四個參數 onSubscribe的接口回調方法,將FromArrayDisposable對象暴露給外部調用。這裏也不再說明。
我們重點來看看FromArrayDisposable中的run方法:
FromArrayDisposable#run
void run() {
T[] a = array;
int n = a.length;
for (int i = 0; i < n && !isDisposed(); i++) {
T value = a[i];
if (value == null) {
actual.onError(new NullPointerException("The " + i + "th element is null"));
return;
}
actual.onNext(value);
}
if (!isDisposed()) {
actual.onComplete();
}
}
array 代表我們剛纔傳入的數組的對象。在for循環中對數組進行遍歷,然後將數組中的值據逐個通過actual.onNext(value)方法發送出去。如果出現錯誤時,則調用actual.onError。完成發送後,在調用actual.onComplete()方法。而我們知道這裏面分別調用的是LambdaObserver對象中的方法。
public final class LambdaObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
private static final long serialVersionUID = -7251123623727029452L;
final Consumer<? super T> onNext;
final Consumer<? super Throwable> onError;
final Action onComplete;
final Consumer<? super Disposable> onSubscribe;
public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete,
Consumer<? super Disposable> onSubscribe) {
super();
this.onNext = onNext;
this.onError = onError;
this.onComplete = onComplete;
this.onSubscribe = onSubscribe;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.setOnce(this, s)) {
try {
onSubscribe.accept(this);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
onError(ex);
}
}
}
@Override
public void onNext(T t) {
if (!isDisposed()) {
try {
onNext.accept(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
get().dispose();
onError(e);
}
}
}
@Override
public void onError(Throwable t) {
if (!isDisposed()) {
lazySet(DisposableHelper.DISPOSED);
try {
onError.accept(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
RxJavaPlugins.onError(new CompositeException(t, e));
}
}
}
@Override
public void onComplete() {
if (!isDisposed()) {
lazySet(DisposableHelper.DISPOSED);
try {
onComplete.run();
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
RxJavaPlugins.onError(e);
}
}
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return get() == DisposableHelper.DISPOSED;
}
}
如上,在LambdaObserver類中onNext,onError,onComplete分別對應的不同的參數回調,從而將接口中的數據傳遞給外部。這樣便完成了調用。
下面列出fromArray和just操作符的簡單demo:
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
Observable.fromArray(list).subscribe(new Consumer<List<String>>() {
@Override
public void accept(List<String> strings) throws Exception {
println("onNext : fromArray : " + strings + "\n");
}
});
Observable.just(list).subscribe(new Consumer<List<String>>() {
@Override
public void accept(List<String> strings) throws Exception {
println("onNext : just : " + strings + "\n");
}
});
輸出結果:
onNext : fromArray : [hello, world]
onNext : just : [hello, world]