TODO-MVP-RXJAVA 原始碼體驗

Cang_Wang發表於2019-02-18

大家好,我是蒼王。

以下是我這個系列的相關文章,有興趣可以參考一下,可以給個喜歡或者關注我的文章。

[Android]如何做一個崩潰率少於千分之三噶應用app–章節列表

相信有關注我的人,都會看過我第一編介紹的Todo-mvp原始碼體驗,這是基礎編。

這一節給大家分享的RXJAVA和MVP設計之間的架構。

當然看這篇文章前,希望你有一定的Rxjava的基礎知識。

一.Lambda

這裡需要介紹一下Java8的新特性,你可以叫這東西為閉包,起是屬於一種函數語言程式設計

官方配置

buildToolVersion需要使用24以上,因為Android N以後的build Tool才支援

TODO-MVP-RXJAVA 原始碼體驗

配置開啟jackOptions

使用新的 Java 8 語言功能,還需使用新的 Jack 工具鏈。新的 Android 工具鏈將 Java 源語言編譯成 Android 可讀取的 Dalvik 可執行檔案位元組碼,且有其自己的 .jack 庫格式,在一個工具中提供了大多數工具鏈功能:重新打包、壓縮、模糊化以及 Dalvik 可執行檔案分包。

TODO-MVP-RXJAVA 原始碼體驗

java版本數需要引用java1.8

TODO-MVP-RXJAVA 原始碼體驗

Instant Run目前不能用於 Jack,在使用新的工具鏈時將被停用。

可以看這裡的介紹:使用 Java 8 語言功能

****2017.3.27*****

剛釋出,就聽到群內的同學說jack要被google廢棄了,詳情請見Future of Java8

TODO-MVP-RXJAVA 原始碼體驗

相容性第三方配置

buildTool在24之前那麼只能使用相容包了

在專案的build gradle需要配置retrolambda的引用

TODO-MVP-RXJAVA 原始碼體驗

也有推薦這樣的配置

TODO-MVP-RXJAVA 原始碼體驗

然後每個module的build.gradle還需要配置

TODO-MVP-RXJAVA 原始碼體驗

Lambda原理

或者你感覺和內部匿名類的縮排後差不多(如Runnable),其原理並非如此。

其實際是使用了invokeDynamic指令,執行時呼叫LambdaMetafactory.metafactory動態的生成內部類,實現了介面,內部類裡的呼叫方法塊並不是動態生成的,只是在原class裡已經編譯生成了一個靜態的方法,內部類只需要呼叫該靜態方法

這裡不做深入的解析,具體可以參考Java 8 動態型別語言Lambda表示式實現原理分析

Lambda還能配合Streams做更多一些操作,具體可以檢視Java Lambda表示式入門

如果你覺得Lambda的函數語言程式設計很爽,就一直使用,但是Lambda有時候的效能並不一定比Java原來的程式碼快,具體效能對比可以看:java8特性lambda基本原理及效能分析

二.原始碼分析

1.相關引用

這裡引用了rxjava和rxandroid兩個RX的庫,

rxandroid用於執行緒切換

還有sqlbrite的庫是響應式資料查詢框架

TODO-MVP-RXJAVA 原始碼體驗

2.執行緒排程

我們看一下TaskPresenter的建立,需要傳入taskRepository,View物件,還有SchedulerProvider物件(RxAndroid執行緒切換)

TODO-MVP-RXJAVA 原始碼體驗

這裡面資料來源也會使用

TODO-MVP-RXJAVA 原始碼體驗

其封裝了三個RxAndroid的執行緒介面

Schedulers.computation( )用於計算任務,如事件迴圈或和回撥處理

Schedulers.io( )用於IO密集型任務,如非同步阻塞IO操作,這個排程器的執行緒池會根據需要增長

AndroidSchedulers.mainThread() 執行在Android UI執行緒上

TODO-MVP-RXJAVA 原始碼體驗

這裡面CompositeSubscription是Subject的集合,可以用於統一釋放。

TODO-MVP-RXJAVA 原始碼體驗

這裡mTasksView.setPresenter會將TasksFragment連線起來。

通過TasksFragment的onResume和onPause生命週期做一些繫結操作

TODO-MVP-RXJAVA 原始碼體驗

TaskPresteners的繫結方法,使用的是載入資料loadTasks

TODO-MVP-RXJAVA 原始碼體驗

3.資料載入

loadTasks裡面會有很多RxJava的操作符,這裡慢慢解析

TODO-MVP-RXJAVA 原始碼體驗

Subscription Observable.subscribe繫結的時候會返回一個Subscription的物件

TODO-MVP-RXJAVA 原始碼體驗

getTasks方法中獲取遠端資料和本地資料

concat的操作符是用於依次將多個資料來源釋放到同一個地方。

filter過濾掉空的任務

first是返回第一條符合要求的資料

起最終返回的是Observable<List<Task>>的資料

TODO-MVP-RXJAVA 原始碼體驗

flatMap將List<Task> tasks物件轉化為Observable<Task>

from會依次返回List中的每個item

filter裡面過濾掉是否進行中的任務(這個是記事本本來的邏輯)

toList將其組裝成List的物件

TODO-MVP-RXJAVA 原始碼體驗

subscribeOn和observeOn都是用來切換執行緒用的

subscribeOn的呼叫,改變了呼叫前序列所執行的執行緒。subscribeOn改變的是subscribe這句呼叫所在的執行緒

observeOn對之前的序列產生的結果先快取起來,然後再在指定的執行緒上,推送給最終的subscriber

請注意這三點!!!

subscribeOn的呼叫切換之前的執行緒。

observeOn的呼叫切換之後的執行緒。

observeOn之後,不可再呼叫subscribeOn切換執行緒

資料正常傳送完畢doOnCompleted會被觸發

TODO-MVP-RXJAVA 原始碼體驗

我們看看Subscribe,感覺我們平時見到的Subscribe有一定的區別,利用了lamba縮排

TODO-MVP-RXJAVA 原始碼體驗

其真實效果是會這樣的

TODO-MVP-RXJAVA 原始碼體驗

這裡需要新增subscription到CompositeSubscription統一管理

TODO-MVP-RXJAVA 原始碼體驗

TaskFragment裡面onPause當中呼叫unsubscribe()

TODO-MVP-RXJAVA 原始碼體驗

然後使用CompositeSubscription清除所有的Subscription

TODO-MVP-RXJAVA 原始碼體驗

4.資料來源變化

我們看看起本地資料來源使用sqlBrite的變化

一開始建立出BriteDataBase mDataBasehelper

TODO-MVP-RXJAVA 原始碼體驗

獲取本地資料

TODO-MVP-RXJAVA 原始碼體驗

返回查詢資料

createQuery返回的是QueryObservable的資料型別,很明顯sqlBrite是相容Observable的轉換

TODO-MVP-RXJAVA 原始碼體驗

可以看到mapToList會將其轉換為Observable的資料

TODO-MVP-RXJAVA 原始碼體驗

5.縮排進入

點選左邊,那個紅色的標誌,可以直接進入到呼叫到縮排的方法

TODO-MVP-RXJAVA 原始碼體驗

這個是直接呼叫processTasks()的方法

TODO-MVP-RXJAVA 原始碼體驗

三.總結

1.Rxjava的識別符號運用

2.Lambda函數語言程式設計,縮排運用和理解

3.SqlBrite資料庫的運用,只是配置RxJava轉換為Observable物件的操作

這節就到這裡,

下一節將會更精彩!!!敬請期待。

群號是316556016,也可以掃碼進群。我在這裡期待你們的加入!!!

TODO-MVP-RXJAVA 原始碼體驗

相關文章