Rxjava近來在技術圈非常火,個人認為其優勢主要是兩點:
- 線程切換
使用Rxjava 可以非常方便指定訂閱者對執行線程,這一點對于安卓開發中來說簡直美妙 - 邏輯清晰
使用Rxjava自帶的幾個函數對數據進行處理, 代碼可以非常整齊,邏輯很清晰。
java作為一個靜態語言,缺少了很多靈活性,使用起來很多時候感覺非常死板,使用Rxjava后其類似函數式語言的特性讓人感覺很靈動。本文主要來分析一下Rxjava源碼是如何將這樣一個個復雜的流程清晰地展現出來的。
先來看一下一個Rxjava使用的一個例子:
Observable.just("a", "b", "c", "d")
.observeOn(Schedulers.computation())
.map(new Func1<String, String>() {
@Override
public String call(String s) {
System.out.print(Thread.currentThread().getName() + ":first--" + s);
return s + s;
}
})
.observeOn(Schedulers.io())
.map(new Func1<String, String>() {
@Override
public String call(String s) {
System.out.print(Thread.currentThread().getName() + ":second--" + s);
return s + s;
}
})
.observeOn(Schedulers.newThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.print(Thread.currentThread().getName());
System.out.print("completed");
}
@Override
public void onError(Throwable e) {
System.out.print("error");
}
@Override
public void onNext(String s) {
System.out.println(s);
}
});
這是一個非常簡單的流程,但是也進行了三次線程的切換,對原始數據進行了兩次map,可以看到使用Rxjava非常優雅,邏輯也很清楚。以下來通過該過程對Rxjava的邏輯進行一些分析。
關鍵類
首先來介紹一下源碼中的幾個重要的類:
Observable
Observable是使用Rxjava的入口,很多重要的方法都在此類中,如常用的create(), map(), filter(), subscribe()等。OnSubscribe
OnSubscribe是Observable中定義的接口,繼承自Action1接口,實際只有一個call方法,但是Rxjava流程中多個環節中的多個類都實現了該接口,之后通過鏈表到方式連接起來。Operator
Operator是Observable中定義的接口,繼承自Func1接口,在Rxjava中需要切換線程的時候均需要實現該接口,java中不能直接傳遞函數,所以只能通過接口的方式來實現。ObserveOnSubseriber
ObserveOnSubseriber是OperatorObserveOn類中的靜態類,它是數據處理的關鍵,該類繼承自Subscriber類,實現基本的onNext,onError, onCompleate方法。Worker
Worker是Scheduler中的一個抽象靜態類,worker是真正執行任務的地方,在worker中含有各個線程池的引用,在這里進行線程的執行。
Rxjava流程
Rxjava流程實際上時一個鏈表結構,代碼例子每一個"."在具體實現中都創建了一個Observable對象,然后通過parent或者source屬性連接起來,當subscibe方法執行后,通過一個list連接各個subscriber,通過鏈表回溯到最開始的地方,然后從最開始處理數據,數據再一級一級傳遞,直到所有數據處理完成。
下邊以一個簡單的流程示意一下,可能不太準確,但是原理差不多:
- 鏈表創建:A(just)-B(lift(線程切換實際是通過lift實現))-C(map)-D(lift)-(map)
- subscribe開始執行代碼
- 通過回溯鏈表創建subscriber list
- 回溯到數據源,開始通過fun對數據進行處理,數據處理通過創建的subscriber list不斷傳輸處理,直到最終的subsciber執行完成。
實際基本過程進行了三遍。
以下是一張根據實際源碼繪制的流程圖,理解原理后結合圖就可以愉快地看源碼了:
可以根據順序標號走一遍流程,基本源碼也就理解一些了。本文實際上并沒有貼源碼,主要介紹一下思路,然后跟著流程圖,源碼必須是自己讀并進行代碼調試才是有效果的。
Rxjava之路
這里mark一下,希望通過閱讀Rxjava, 自己可以實現一個簡易的函數式流程。
NotRxJava guide for lazy folks中作者嫌Rxjava代碼量大,于是介紹了一下自己的思路。文中的代碼并不能實現一個非常安全可靠的代碼庫,但是其思路很值得學習。
另谷歌開源了ageragithub,也是一個函數式的例子,代碼量比Rxjava要少許多,其亮點是實現了數據的分離,“Push event,pull data model”是其目標。其源碼思路非常清晰,簡直是寫代碼的典范。github,MaterialDesignExample中是MaterialDesign使用的例子,其中使用agera對網絡訪問到數據渲染到流程進行控制,數據來源是知乎日報,感興趣的可以看下。
參考
https://gank.io/post/560e15be2dca930e00da1083
http://blog.csdn.net/wl9739/article/details/52212275
http://yarikx.github.io/NotRxJava/