RxJava 現在用的比較廣泛了,尤其是用在網絡中,我們來看看它到底是什麼,怎麼用。這裏以 1.1 版本爲例,比較早起的本,使用的時候,先註明引用
implementation 'io.reactivex:rxjava:1.1.7'
我們先來看個簡單的例子,這是在Java中寫的,
private static void initRxJava1(){
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
System.out.println(" create " + Thread.currentThread().getName() );
// 重點一
subscriber.onNext("hi");
subscriber.onCompleted();
}
})
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println( " onCompleted " );
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
int num = Runtime.getRuntime().availableProcessors();
System.out.println(s + " " + num + " " + Thread.currentThread().getName());
}
});
}
這個例子中,打印的值爲
create main
hi 4 main
onCompleted
我們知道,RxJava 是響應鏈式編程,顧名思義就是從上往下相應的編程,上面知識一個最簡單的例子,我們來分析一下代碼,看看它是怎麼從上往下執行的
Observable:
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(RxJavaHooks.onCreate(f));
}
RxJavaHooks:
public static <T> Observable.OnSubscribe<T> onCreate(Observable.OnSubscribe<T> onSubscribe) {
Func1<OnSubscribe, OnSubscribe> f = onObservableCreate;
if (f != null) {
return f.call(onSubscribe);
}
return onSubscribe;
}
在這裏,我們可以簡化點,認爲 RxJavaHooks.onCreate(f) 中返回的就是 f 值本身,這樣,通過第一步 Observable.create() 方法就創建一個 Observable 對象,暫時記爲 Ob1,它裏面的 onSubscribe 屬性紀委 onS1;繼續往下看,此時調用了 subscribe() 方法,傳入了 Subscriber 對象, Subscriber 是個抽象類,它實現了 Observer 和 Subscription 接口,其實這裏傳入一個 Observer 對象也是可以的,它會被包裝一層,轉化爲 ObserverSubscriber 對象繼續調用 subscribe(Subscriber<? super T> subscriber)方法,ObserverSubscriber 是 Subscriber 的子類,是個裝飾模式。繼續看 subscribe() 方法,稱傳入的 Subscriber 對象爲 Sub1,
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
subscriber.onStart();
if (!(subscriber instanceof SafeSubscriber)) {
subscriber = new SafeSubscriber<T>(subscriber);
}
try {
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
return RxJavaHooks.onObservableReturn(subscriber);
} catch (Throwable e) {
...
return Subscriptions.unsubscribed();
}
}
這是簡化後的代碼,其實 try...catch 中可以簡化一行代碼 observable.onSubscribe.call(subscriber); 也就是說可以是
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
subscriber.onStart();
if (!(subscriber instanceof SafeSubscriber)) {
subscriber = new SafeSubscriber<T>(subscriber);
}
try {
observable.onSubscribe.call(subscriber);
return subscriber;
} catch (Throwable e) {
...
return Subscriptions.unsubscribed();
}
}
此時,在 Ob1 中,subscriber 對象傳進來時是 Sub1,先執行它的 onStart() 方法;然後包裹一層,轉爲爲 SafeSubscriber 對象,此時記做 SafeSub1, observable.onSubscribe 對應的是 onS1,也就是說它調用了 call() 方法,裏面傳入的對象是 SafeSubscriber 類型的 SafeSub1,看看它的代碼
public class SafeSubscriber<T> extends Subscriber<T> {
private final Subscriber<? super T> actual;
boolean done;
public SafeSubscriber(Subscriber<? super T> actual) {
super(actual);
this.actual = actual;
}
@Override
public void onCompleted() {
try {
actual.onCompleted();
} catch (Throwable e) {
throw new OnCompletedFailedException(e.getMessage(), e);
}
}
@Override
public void onNext(T args) {
try {
if (!done) {
actual.onNext(args);
}
} catch (Throwable e) {
Exceptions.throwOrReport(e, this);
}
}
}
這是簡化後的代碼,說是安全,其實就是添加了個boolean屬性,防止重複執行,例如 onNext() 方法中就是保留的例子。SafeSubscriber 是 Subscriber 的子類,看它構造方法中調用了 super(actual) 方法,把傳進來的 Sub1 傳給了父類,這裏可以先不用看它的父類,對邏輯沒影響。繼續回到 observable.onSubscribe.call(subscriber) 這行代碼,此時執行了 initRxJava1() 中的 new Observable.OnSubscribe<String>() 對象中的 call() 回調,打印了 create main 字符串,然後執行了 重點一 的代碼,如果沒有在這兩行代碼,整個流程到此結束,我們看看,此時 subscriber 就是 SafeSubscriber 類型,即 SafeSub1 , 執行的 onNext() 和 onCompleted() 都是它內部屬性也就是 Sub1 對應的方法,Sub1 就是 initRxJava1() 方法中的 new Subscriber<String>() 對象,此時執行它裏面的打印方法,這個調用流程就是這樣。
看看方法 initRxJava2(),會有個不一樣的體驗效果
private static void initRxJava2(){
Observable
.just("hello")
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println( " onCompleted " );
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
int num = Runtime.getRuntime().availableProcessors();
System.out.println(s + " " + num + " " + Thread.currentThread().getName());
}
});
}
打印的值爲
hello 4 main
onCompleted
這個明顯沒有地方調用 onNext() 和 onCompleted() 方法,爲什麼會調用呢?看看它裏面的代碼
public static <T> Observable<T> just(final T value) {
return ScalarSynchronousObservable.create(value);
}
ScalarSynchronousObservable:
public static <T> ScalarSynchronousObservable<T> create(T t) {
return new ScalarSynchronousObservable<T>(t);
}
protected ScalarSynchronousObservable(final T t) {
super(RxJavaHooks.onCreate(new JustOnSubscribe<T>(t)));
this.t = t;
}
static final class JustOnSubscribe<T> implements OnSubscribe<T> {
final T value;
JustOnSubscribe(T value) {
this.value = value;
}
@Override
public void call(Subscriber<? super T> s) {
s.setProducer(createProducer(s, value));
}
}
這裏是生成了一個 ScalarSynchronousObservable 對象,它是 Observable 的子類,ScalarSynchronousObservable 的構造方法中可以忽略 RxJavaHooks 的方法代碼,直接理解爲 super(new JustOnSubscribe<T>(t)) 即可,這裏是創建了一個 JustOnSubscribe 對象傳給了父類,即 onSubscribe 屬性爲 JustOnSubscribe 對象。繼續看 initRxJava2() 中方法,這裏也執行到了 subscribe() 方法,老樣子,先把 Subscriber 對象包裹一層,轉換爲 SafeSubscriber 對象,然後執行 JustOnSubscribe 的 call() 方法,方法中的形參就是 SafeSubscriber 類型,先看看 createProducer(s, value) 方法
static <T> Producer createProducer(Subscriber<? super T> s, T v) {
if (STRONG_MODE) {
return new SingleProducer<T>(s, v);
}
return new WeakSingleProducer<T>(s, v);
}
這裏創建的是 WeakSingleProducer 對象
static final class WeakSingleProducer<T> implements Producer {
final Subscriber<? super T> actual;
final T value;
boolean once;
public WeakSingleProducer(Subscriber<? super T> actual, T value) {
this.actual = actual;
this.value = value;
}
...
}
s.setProducer(createProducer(s, value)) 中的 s 是 SafeSubscriber 類型,它是 Subscriber 的子類,調用了 setProducer() 方法,看看它的代碼
public abstract class Subscriber<T> implements Observer<T>, Subscription {
private static final long NOT_SET = Long.MIN_VALUE;
private final SubscriptionList subscriptions;
private final rx.Subscriber<?> subscriber;
private Producer producer;
private long requested = NOT_SET; // default to not set
protected Subscriber() {
this(null, false);
}
protected Subscriber(rx.Subscriber<?> subscriber) {
this(subscriber, true);
}
protected Subscriber(rx.Subscriber<?> subscriber, boolean shareSubscriptions) {
this.subscriber = subscriber;
this.subscriptions = shareSubscriptions && subscriber != null ? subscriber.subscriptions : new SubscriptionList();
}
public void onStart() {
// do nothing by default
}
public void setProducer(Producer p) {
long toRequest;
boolean passToSubscriber = false;
synchronized (this) {
toRequest = requested;
producer = p;
if (subscriber != null) {
// middle operator ... we pass through unless a request has been made
if (toRequest == NOT_SET) {
// we pass through to the next producer as nothing has been requested
passToSubscriber = true;
}
}
}
// do after releasing lock
if (passToSubscriber) {
subscriber.setProducer(producer);
} else {
// we execute the request with whatever has been requested (or Long.MAX_VALUE)
if (toRequest == NOT_SET) {
producer.request(Long.MAX_VALUE);
} else {
producer.request(toRequest);
}
}
}
}
裏面比較重要的是構造方法和 setProducer() 這個方法,由於調用的一個參數的構造方法,所以 subscriber 和 subscriptions 都有值,此時 setProducer()中,形參 Producer 是 WeakSingleProducer 類型, s 是 SafeSubscriber 類型,setProducer() 中 synchronized 代碼塊中,會執行到 passToSubscriber = true這一步,然後就是 subscriber.setProducer(producer) 這行代碼,此時 subscriber 就是 initRxJava2() 中的 new Subscriber<String>() 對象,producer 是 WeakSingleProducer,執行後,還是會執行
setProducer(Producer p) 方法,區別是此時方法所屬的對象是 Subscriber 而非 SafeSubscriber,我們繼續看,由於此時 subscriber 爲null,所以 passToSubscriber 值是false,執行 else 中的操作 producer.request(Long.MAX_VALUE) 代碼,因此回到了 WeakSingleProducer 中
static final class WeakSingleProducer<T> implements Producer {
final Subscriber<? super T> actual;
final T value;
boolean once;
public WeakSingleProducer(Subscriber<? super T> actual, T value) {
this.actual = actual;
this.value = value;
}
@Override
public void request(long n) {
Subscriber<? super T> a = actual;
T v = value;
try {
a.onNext(v);
} catch (Throwable e) {
return;
}
a.onCompleted();
}
}
簡化後代碼,此時 actual 就是 SafeSubscriber ,因此調用還是它內部的 onNext() 、onCompleted() 方法,它內部執行 initRxJava2() 中 new Subscriber<String>() 對象的方法。故此,我們沒有明文像 initRxJava1() 中的 重點一 代碼,卻也執行了打印方法。
private static void initRxJava3(){
Observable
.just("hello","world")
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println( " onCompleted " );
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
int num = Runtime.getRuntime().availableProcessors();
System.out.println(s + " " + num + " " + Thread.currentThread().getName());
}
});
}
注意,just() 方法中傳入的是兩個字符串,看看運行的結果
hello 4 main
world 4 main
onCompleted
onNext() 方法執行了兩次,這是爲什麼呢?老規矩,看源碼
public static <T> Observable<T> just(T t1, T t2) {
return from((T[])new Object[] { t1, t2 });
}
public static <T> Observable<T> empty() {
return EmptyObservableHolder.instance();
}
public static <T> Observable<T> from(T[] array) {
int n = array.length;
if (n == 0) {
return empty();
} else
if (n == 1) {
return just(array[0]);
}
return create(new OnSubscribeFromArray<T>(array));
}
由此可以看出,如果數組長度爲0,返回的是 EmptyObservableHolder 中的單利對象,它只會執行 Subscriber 的 onCompleted() 方法;數組長度爲1時,還是調用 just() 方法;數組長度超過1時,這裏又創建了 OnSubscribeFromArray 對象。
public final class OnSubscribeFromArray<T> implements Observable.OnSubscribe<T> {
final T[] array;
public OnSubscribeFromArray(T[] array) {
this.array = array;
}
@Override
public void call(Subscriber<? super T> child) {
child.setProducer(new FromArrayProducer<T>(child, array));
}
static final class FromArrayProducer<T>
extends AtomicLong
implements Producer {
final Subscriber<? super T> child;
final T[] array;
public FromArrayProducer(Subscriber<? super T> child, T[] array) {
this.child = child;
this.array = array;
}
@Override
public void request(long n) {
...
fastPath();
...
}
void fastPath() {
final Subscriber<? super T> child = this.child;
for (T t : array) {
if (child.isUnsubscribed()) {
return;
}
child.onNext(t);
}
if (child.isUnsubscribed()) {
return;
}
child.onCompleted();
}
}
}
這個是簡化後的代碼,看過 initRxJava2() 方法中的代碼分析,知道 OnSubscribeFromArray 中的 call() 方法中的參數 child 是 SafeSubscriber 類型,所以執行 SafeSubscriber 的 setProducer() 方法,最終執行到 FromArrayProducer 對象中的 request() 方法,經過判斷,執行 fastPath() 方法,這個方法邏輯比較簡單,先是遍歷數組,執行 child 也就是 SafeSubscriber 的 onNext() 方法,遍歷結束後,執行 onCompleted() 方法,SafeSubscriber 是個包裝類,對應執行的是 initRxJava3() 中的 new Subscriber<String>() 對象中的 onNext() 和 onCompleted() 方法。
private static void initRxJava4(){
Observable
.just("a", "b", "c", "d")
.map(new Func1<String, String>() {
@Override
public String call(String s) {
return s + s;
}
})
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println( " onCompleted " );
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
System.out.println(s + " " + Thread.currentThread().getName());
}
});
}
這個方法在上面的基礎上添加了個 map 方法,它的作用是類型轉換,我們這裏僅僅是讓傳入的字符串由單個變爲雙個,來看它的原理,just() 方法創建了 Observable A,它裏面屬性 onSubscribe 是 OnSubscribeFromArray, OnSubscribeFromArray 中包含我們傳入的字符串數組;map() 方法是在 A 中又創建了一個 Observable 對象,命名爲B,屬性onSubscribe是
OnSubscribeMap 對象,它把 A 和 map() 中的類型轉換Func1作爲參數傳進構造方法中
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return create(new OnSubscribeMap<T, R>(this, func));
}
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(RxJavaHooks.onCreate(f));
}
此時是在 B 中,繼續看 subscribe() 方法,我們知道,此時把 initRxJava4() 中的 new Subscriber<String>() 對象轉換爲 SafeSubscriber 類型,然後調用
OnSubscribeMap 的 call(subscriber) 方法,形參是 SafeSubscriber
public void call(final Subscriber<? super R> o) {
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
source.unsafeSubscribe(parent);
}
此時,source 是 Observable A,parent 構造方法中的兩個對象是 SafeSubscriber 和 map()中的類型轉換Func1,看看 unsafeSubscribe() 方法
public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
onSubscribe.call(subscriber);
...
}
簡化後的代碼就是這樣,此時 onSubscribe 是 OnSubscribeFromArray ,subscriber 是 MapSubscriber, call() 方法爲
public void call(Subscriber<? super T> child) {
child.setProducer(new FromArrayProducer<T>(child, array));
}
有沒有很熟悉的感覺,這裏是老套路了,看看 MapSubscriber 中的方法
@Override
public void setProducer(Producer p) {
actual.setProducer(p);
}
此時 actual 是它構造方法傳進來的 SafeSubscriber,p 是 FromArrayProducer ,此時看父類中的 setProducer() 方法,上面分析過,先是 SafeSubscriber中的 setProducer() 方法,會走到 subscriber.setProducer(producer) 這一行代碼,此時 subscriber 代表的是 initRxJava4() 中的 new Subscriber<String>() 對象,然後繼續,這一次會執行到 producer.request(Long.MAX_VALUE) 這行代碼,此刻 producer 仍舊是 FromArrayProducer,上面已經有了,再次看它中的代碼
static final class FromArrayProducer<T>
extends AtomicLong
implements Producer {
final Subscriber<? super T> child;
final T[] array;
public FromArrayProducer(Subscriber<? super T> child, T[] array) {
this.child = child;
this.array = array;
}
@Override
public void request(long n) {
...
fastPath();
...
}
void fastPath() {
final Subscriber<? super T> child = this.child;
for (T t : array) {
if (child.isUnsubscribed()) {
return;
}
child.onNext(t);
}
if (child.isUnsubscribed()) {
return;
}
child.onCompleted();
}
}
child 是 MapSubscriber,也就是說會執行它的 onNext(t) 和 onCompleted() 方法,我們just()方法中數組數據,就是在這裏通過遍歷分發出去的,看看 MapSubscriber 的源碼
static final class MapSubscriber<T, R> extends Subscriber<T> {
final Subscriber<? super R> actual;
final Func1<? super T, ? extends R> mapper;
public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
this.actual = actual;
this.mapper = mapper;
}
@Override
public void onNext(T t) {
R result;
try {
result = mapper.call(t);
} catch (Throwable ex) {
return;
}
actual.onNext(result);
}
@Override
public void onCompleted() {
actual.onCompleted();
}
@Override
public void setProducer(Producer p) {
actual.setProducer(p);
}
}
簡化後的代碼,actual 是 SafeSubscriber ,mapper 是 map()中的類型轉換Func1,都是通過構造方法傳遞進來的。此時 mapper.call(t) 執行了數據轉換,得到新的數據 result,然後調用了 SafeSubscriber 的 onNext(result) 方法,進而調用 initRxJava4()中的 new Subscriber<String>() 對象中的方法,onCompleted() 也是同樣的道理。
private static void initRxJava5(){
Observable
.just("a b c", "12 3")
.flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String file) {
return Observable.from(file.split(" "));
}
})
.filter(new Func1<String, Boolean>() {
@Override
public Boolean call(String s) {
return "a".equals(s);
}
})
.map(new Func1<String, String>() {
@Override
public String call(String s) {
return s + s;
}
})
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println( " onCompleted " );
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
System.out.println(s + " " + Thread.currentThread().getName());
}
});
}
運行的結果是
a main
onCompleted
這個方法中添加了轉換、攔截等功能,flatMap() 方法把 Observable 對象中的一個數組中的兩個對象,轉換爲了兩個 Observable 對象,每個對象中的數組內容是 "a b c" 、 "12 3" 這兩個字符串分別根據 " " 來拆分出來的新數組 {a,b,c} 、{12,3} ,通過 Observable.from() 生成對象;接着就是攔截功能,看看裏面的判斷,這裏是只有返回 true 纔會往下面執行,false的話就到此爲止了,繼續下一個數據;map() 中是個轉換,把字符串疊加;最後一個方法是打印。這個方法的源碼和前面一樣,都是通過包裝和回調,執行代碼。
RxJava 的初級用法就是回調和包裝類,單純這樣使用基本無用,本篇文章的介紹只是一個入門。