android 開發(fā)框架整合(Rxjava+Retrofit二次封裝+dbFlow+rxbus分發(fā)事件機制+glide等)

前言:

我們知道rxjava+retrofit+mvp已經(jīng)出現(xiàn)很久了。由于最近項目需要大整改,故此封裝一個比較適用的框架。首先網(wǎng)路框架暫時選用了最新的框架:rxjava+retrofit。至于mvp的話由于之前別人項目寫的太過雜亂又經(jīng)過多人之手,暫時無力修改。當(dāng)然,封裝沒有絕對的好與壞,只有適不適合。每個公司有每個公司的規(guī)則。

參考了很多網(wǎng)上資料,最終整出了一套屬于自己的網(wǎng)絡(luò)框架。這里特別感謝csdn的大神 wzgiceman??

參考鏈接:blog.csdn.net/wzgiceman/article/details/52995205

從這篇文獻中得到了自己的思路,因為使用retrofit的童鞋大多數(shù)都是使用了內(nèi)置的gson解析,這樣有個問題:并不是每個公司的后臺都會乖乖地給你返回想要的 jsonObject。就比如我的后臺 result如果是集合則返回類似 {"result" :"[{xxx},{xxx}]"},如果是對象則返回 {"result":"{xxxxx}"這樣想都不用想,不處理直接使用的話肯定會報錯。所以修改 .addConverterFactory(GsonConverterFactory.create())-->.addConverterFactory(ScalarsConverterFactory.create()) 以string的數(shù)據(jù)返回。這里有人會問,這樣話不是更加不方便了嗎?明明人家都幫你解析好了你還多此一舉,而且可能只有你公司后臺是這樣返回的。

這里要說下:其實如果沒有這個框架,平常我們使用其他框架,比如xutils等等都是返回json字符串然后手動解析,這樣有個好處:更加靈活,擴展性更強。再舉個例子:我們的另一個項目返回的格式居然是 “{"status":"1"}”. 認(rèn)真看下它是一個字符串(不知道我們后臺腦子是不是抽了)。這樣不用說同樣會報錯。其實這里這個例子是為了說明,我們不用使用內(nèi)置的gson解析,而是攔截得到的數(shù)據(jù)然后操作成我們想要的數(shù)據(jù)。換句話說,哪天你和你后臺吵架了,人家不幫你改那就尷尬了。

我們看下干貨:

封裝前:


未封裝

首先我們可以看到?jīng)]有封裝的框架代碼很長,使用方法是配置okhttp,然后用observable去subscribe一個 subscriber ?緊接著就是四個回調(diào)。本人是很不喜歡這么多的回調(diào),如果不用mvp模式編寫的話那么業(yè)務(wù)邏輯的代碼都要寫在activity中,而且這僅僅是一個接口,如果多個接口呢?

同時可以看到其實很多代碼是重復(fù)多余的。比如okhttp是配置。onCompleted、onStart這兩個回調(diào)在本人看來也是多余的。其實要用到的onNext(得到數(shù)據(jù)然后處理)、onError(錯誤的處理)。

接之前的話題,怎么才能將數(shù)據(jù)攔截靈活處理呢? 我們可以看到真正得到數(shù)據(jù)的是onNext ,而之前也說了,回調(diào)是在subscriber重寫的。那么我們的思路就來了:寫一個類繼承subscriber然后重寫onNext 。得到的數(shù)據(jù)我們不就可以任意蹂躪了嗎? 等到數(shù)據(jù)處理成自己想要的格式再用一個接口回調(diào)返回出去不就好了?

順著這個思路我們寫一個ProgressSubscriber繼承Subscriber ?看到類名就想到了我們在訪問的同時加一個加載框。而回到中onStart可以做對話框顯示的初始化。 onComplete則消除對話框。


而onNext則是真正的數(shù)據(jù)處理


再來看下那個接口


好了我們的Subscriber就寫好了。前文也說了 由于后臺的任性返回了不同的結(jié)構(gòu)。不過通過我們的處理之后不管之后返回什么結(jié)構(gòu)都可以解析,我們只要傳一個解析的實體類就可以了。真的很方便。

接下來,我們重點用一個例子看看使用過程。


依照這個過程
兩個訪問的接口

service有了,我們需要一個retrofit。而我把這些統(tǒng)一寫到一個工具類中


對象都有了之后只要做subscirbe的操作:


我們需要注冊一個 subscriber進去。而之前我們已經(jīng)有了一個progressSubscriber 。同樣這個部分的操作我們都在HttpManager封裝。


基本的操作就好了

我們再看下activity 中具體的調(diào)用


這是我們的activity中的調(diào)用。 onNext中我們通過每個接口中不同的method去區(qū)分具體的接口。然后做不同的操作。兩個接口僅僅也是寫了這些代碼而已。

總結(jié):

其實我也是貼了部分重要代碼而已。做這個的目的還是為了能夠靈活處理返回的數(shù)據(jù)。主要的思路再說一遍:寫一個類繼承subscriber并重寫onNext 然后得到的數(shù)據(jù)我們再用一個接口回調(diào)。至于之后的那些封裝只是為了讓代碼更加簡潔而已,每個人有每個人的習(xí)慣和寫法,這里不做統(tǒng)一。

最后分享這個框架 接下去還會進行改進以及添加更多的工具:圖片處理框架 glide、數(shù)據(jù)庫框架dbflow等等。還是那句話:合適的才是好用的!

百度網(wǎng)盤 鏈接:http://pan.baidu.com/s/1dFKTDJj 密碼:9rk9

github :github.com/xmrkwzw/rxRetrofit-master

更新

2017/8/23 :嵌套接口的封裝

昨天一個小伙伴突然提了一個疑問:如果一個接口要在另一個接口請求結(jié)果的前提下完成(嵌套接口)那要怎么做?

我想都沒想


那不是可以在onnext里面做完繼續(xù)做嗎? 然后仔細(xì)想想 這個是針對單個接口的根據(jù)method的條件做if....else的判定。假設(shè)第一次請求是 BaseInfoApi.BASE_INFO_METHOD.然后第二次請求是BaseInfoApi.CIVILIZATION_METHOD那么第二次請求完就不會進入第一個的條件了。所以導(dǎo)致第二個的回調(diào)沒法做。

那么有什么辦法可以做嵌套接口的開發(fā)呢? 答案是肯定的:我們知道rxjava有很多關(guān)鍵字,其中有一個是flatmap.剛好就是可以做接口的嵌套。

基于這個條件我們在baseApiInfo中又寫了一個方法


可以看到,我們先調(diào)用了 getBaseInfo的一個接口然后用flatmap關(guān)鍵字轉(zhuǎn)化成另一個observable 然后調(diào)用了getcivilization的接口。這里需要注意的是func1里面的參數(shù)列表。上文我們也說過,我們不再用內(nèi)置的gson插件而是使用string的方式重新解析。所以這里么的參數(shù)列表一定要和接口的service7一致

? ?public interfaceHttpApiService {

? ? ? ? ? ? ? @GET("brand/brandBaseInfo")

? ? ? ? ? ? ? ?ObservablegetBaseInfo(@Query("seqNum") String seqNum);

? ? ? ? ? ? ? ?@GET("brand/getMoralRateData")

? ? ? ? ? ? ? ?ObservablegetCivilization(@Query("classId") String classId);

? }

然后注冊下subscriber.此處我是直接注冊了progresssubscriber.這里有個bug暫不知道原因。 ?第二個回調(diào)應(yīng)該和上面調(diào)用的httpRequest(observable);一樣。 這個方法進去實際上做的也是同樣的操作,但是不知道為什么回調(diào)的始終是第一個接口的結(jié)果,可是按道理第一個接口已經(jīng)在 flatmap轉(zhuǎn)換中的call方法回調(diào)了。所以這個問題還有待解決。但是總的來說 嵌套接口已經(jīng)用flatmap解決了,而且較之其他的方式,這個方式是最好的,代碼邏輯也是最合理的。

DBFlow

為什么使用DBFlow:綜合了 ActiveAndroid, Schematic, Ollie,Sprinkles 等庫的優(yōu)點。同時不是基于反射,所以性能也是非常高,效率緊跟greenDAO其后。基于注解,使用apt技術(shù),在編譯過程中生成操作類,使用方式和ActiveAndroid高度相似,使用簡單。

特性:

無縫支持多個數(shù)據(jù)庫;

使用annotation processing提高速度;

ModelContainer類庫可以直接解析像JSON這樣的數(shù)據(jù);

增加靈活性的豐富接口。

使用:

project build.gradle



app build.gradle


問題:

這里發(fā)現(xiàn)了一個問題,假如你的項目中使用了module 而如果將dbflow的依賴添加到 module的build.gradle中就會報初始化錯誤。所以建議將dbflow依賴寫在 app的build.gradle中

Api

使用dbflow的過程其實有遇到很多問題。最大的問題是假如你不翻墻,我們大天朝的百度幾乎都是復(fù)制來復(fù)制去的,沒有什么參考的意義。本人在使用的過程遇到了問題通過 stackoverflow一步步查找最終找到了比較好的一個api

agrosner.gitbooks.io/dbflow/content/SQLiteWrapperLanguage.html

增:insert


插入的方式有

1 Model.insert()

如:dbflowModel.insert();

2 SQLite.insert()


3插入一個集合


使用事務(wù)

除了上述方法 當(dāng)然也可以通過遍歷然后通過 model.insert();?? 但是如果數(shù)據(jù)量很大的情況下建議開啟事務(wù)

刪 delete


其中 使用 Delete.table(Table table)是清空表數(shù)據(jù)的作用

改 update


查 query

使用 SQLite.select().from(DBFlowModel.class).querySingle(); 查找一個對象

SQLite.select().from(DBFlowModel.class).queryList(); 查找一個集合對象

同樣還有以下api

事務(wù)

事務(wù)是一個數(shù)據(jù)必須具備的,如果保存10000條數(shù)據(jù),一條一條保存必然是很慢的,所以就需要用到事務(wù),批量保存。DBFlow的事務(wù)非常的強大,同時使用也很復(fù)雜;

查詢


保存


如果是新增表無需做特別的處理,直接修改AppDatabase的版本號即可。

如果需要新增字段,除了需要修改AppDatabase的版本號外,還需要做特殊的處理,DBFlow的描述是:Migrations。

例子:對People新增一個email字段

第1步,修改數(shù)據(jù)庫版本號

第2步,需要修改數(shù)據(jù)表對象結(jié)構(gòu),增加email

第3步,執(zhí)行第二步之后,需要build(Android studio的build->Make?Project、Mac的童鞋直接command+F9),通過apt更新People_Table,接下來編寫Migrations

類名可以更加自己喜歡定義,我個人的規(guī)則是,按照數(shù)據(jù)庫版本號和需要更新的數(shù)據(jù)表來命名,需要注意是:version = 2

數(shù)據(jù)庫升級就大功告成了。

基本的使用就這些,其他api用法請往這邊看?https://agrosner.gitbooks.io/dbflow/content/SQLiteWrapperLanguage.html

Rxbus

它不是一個庫,而是一個文件,最短實現(xiàn)只有短短30行代碼。RxBus本身不需要過多分析,它的強大完全來自于它基于的RxJava技術(shù)。響應(yīng)式編程(Reactive Programming)技術(shù)這幾年特別火,RxJava是它在Java上的實作。RxJava天生就是類似sub/pub的觀察者模式,而且很容易處理線程切換

rxbus并沒有一個統(tǒng)一的標(biāo)準(zhǔn),他是一種概念。如果要看概念的,網(wǎng)上也是有很多資料。這里不做詳解

在用過rxjava前相信很多人使用過eventbus?

如果你的項目中已經(jīng)開始使用EventBus,沒有必要特意換用RxBus。

如果你的項目計劃引入RxJava,并認(rèn)為統(tǒng)一風(fēng)格很重要,啟用RxBus,拋棄EventBus沒有問題。但是請了解RxBus的問題,并關(guān)注RxBus的進展,最好能用Rx的方式解決這個問題。

使用:

推薦一個不錯的rxbus?github.com/xmrkwzw/Rxbus-1?如果只是做單獨的post發(fā)送消息網(wǎng)上有很多資源。而就發(fā)送粘性事件(stickyEvent) 我覺得這個封裝的很不錯。

用法 :

訂閱者


注冊與反注冊



粘性事件接收,注解中一定要記得加上sticky = true


發(fā)送者



glide

glide相信很多人都在用。而這次用到的是glide4.0 同時支持kotlin。

glide4.0在用法上和之前確實有不小的改變。新增的API(RequestBuilder,RequestOptions)

具體的用法可以到官網(wǎng)查看api?

bumptech.github.io/glide/

或者查看某作者的整合博客

blog.csdn.net/github_33304260/article/details/72526237

這里只貼出部分功能的代碼


一般設(shè)置



可以看出官方把有些方法都集成到了上述的兩個api中。具體的其他方法請看官網(wǎng)介紹。

以上框架就基本搭建好了,如有什么不足和bug,歡迎提出意見和建議。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容