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對網路訪問到資料渲染到流程進行控制,資料來源是知乎日報,感興趣的可以看下。
參考
gank.io/post/560e15…
blog.csdn.net/wl9739/arti…
yarikx.github.io/NotRxJava/