Android 網絡請求封裝總結Moshi+Coroutines+Retrofit

Android 網絡請求封裝總結

Android Http 網絡請求封裝,使用 Kotlin+Moshi+Coroutines+retrofit等封裝處理Http請求,支持多個域名多態數據返回。封裝要達到的目的特性就一個:簡潔的同步代碼風格處理網絡異步請求!
GitHub 演示(NetWork分支):https://github.com/AnyLifeZLB/Android-Architecture/tree/NetWork

為什么要使用以下技術棧:

  • 協程 Coroutines 而不是rxjava:rxjava 是個好東西但不是官方的,學習成本也高,后期官方推薦kotlin,引入協程簡潔優雅處理網絡請求
  • Moshi 而不是Gson: Moshi 天生支持Kotlin空安全,使用CodeGen生成代碼比Gson反射注解效率高
  • Retrofit 而不是直接OKHTTP :因為Retrofit使用注解+動態代理來優雅的封裝調度OKHTTP去執行
  • 哪怕是使用自家的OkHttp,哪怕底層調用的始終是OkHttpClient,也需要依賴一個抽象的retrofit2.Call接口,依賴于抽象,而不是依賴于具體
  • 同步的方式寫異步請求。簡潔,簡潔,目標只有一個:使用快捷方便簡潔 !

封裝能達到的效果/目標

    1. 多域名Host,多個環境,多態返回數據處理
    1. 使用最新穩定的技術方案實現快捷穩定的請求交互
    1. 封裝各種Http異常處理,服務器返回的各種異常json 數據

1.關于 Retrofit

Retrofit的設計非常插件化而且輕量級,接口設計真的是非常高內聚而且低耦合,精妙的設計是極佳的研究素材。Retrofit底層請求 默認由OKHTTP執行,
Retrofit主要負責調度;其中 Retrofit中定義了4個接口:

  • Callback<T> 接口
    這個接口就是retrofit請求數據返回的接口,只有兩個方法

    • void onResponse(Response<T> response);
    • void onFailure(Throwable t);
  • Converter<F, T>
    這個接口主要的作用就是將HTTP返回的數據解析成Java對象,主要有Xml、Gson、protobuf等等,你可以在創建Retrofit對象時添加你需要使用的Converter實現(看上面創建Retrofit對象的代碼)

  • Call<T.>
    這個接口主要的作用就是發送一個HTTP請求,Retrofit默認的實現是OkHttpCall<T>,你可以根據實際情況實現你自己的Call類,這個設計和Volley的HttpStack接口設計的思想非常相似,子類可以實現基于HttpClient或HttpUrl Connection的HTTP請求工具,這種設計非常的插件化,而且靈活

  • CallAdapter<R,T>
    網絡請求執行器(Call)的適配器CallAdapter用于對原始Call進行再次封裝,如Call<R>到Observable<R>或者本SDK 中的HttpResult<T>

2.協程Coroutines

「協程 Coroutines」源自 Simula 和 Modula-2 語言,這個術語早在 1958 年就被 Melvin Edward Conway 發明并用于構建匯編程序,說明協程是一種編程思想,并不局限于特定的語言; 協程設計的初衷是為了解決并發問題,讓 「協作式多任務」 實現起來更加方便。

在Android中使用協程的環境分為下面五種環境:

  • 網絡請求
  • 回調處理
  • 數據庫操作
  • 文件操作
  • 其他耗時操作

3.數據返回封裝

字段 說明
code 業務返回狀態碼,注意業務狀態碼不要和標準Http狀態碼混淆
message 返回補充說明信息
data[T] 期待正常返回的業務數據

假設公司各個業務服務器返回的Http Json數據格式都差不多三個大字段code[int] + msg[str] +data[T] ,名稱允許自定義不同
這里我們統一約定稱含有三個類似字段為包裝數據Http wrapper data定義為HttpWrapper.kt,每個Http請求正常都會含有這三個字段,
data字段很自然的我們會使用范型T來表示,這也是Http 請求回來實際參與業務處理的部分 .

  • [code] 本字段表示業務服務是否獲取了期待的數據,一般0或200 表示成功,其他值表示沒有獲取正常期望的業務數據如權限不足
    另外,這個業務code 要和標準Http 請求響應的編碼區分清除,標準Http 2xx 表示成功,4xx表示客戶端錯誤,5xx 是服務器錯誤
    強烈建議業務code 的返回值不要和標準Http 請求響應的編碼有重合避開[2xx,5xx]范圍
  • [msg] msg 是對業務code的補充說明,可以簡單的是OK 或者對應的異常提示信息
image.png

如果你的App 請求的業務服務器返回json不包含類似這三字段結構也沒關系:不是標準的HttpWrapper了,不需要實現HttpWrapper impl,相應的判斷需要使用的時候進行補齊。

//不是標準的HttpWrapper
viewModelScope.launch {
    when (val result = EuropeanaApiService.getService().getEuropData()) {
        is HttpResult.Success -> {
            if(result.data.success){
                Log.e("Success", MoshiUtils.toJson(result.data.items)) //多一層鏈路.item
            }else{
                Log.e("code is not ok","")
            }
        }

        is HttpResult.Failure -> {
            Log.e("Failure", result.message + "  -----  " + result.code)
        }
    }
}

而有標準HttpWrapper 結構就能寫法上更簡潔,少了一層判斷和一層數據拆箱 result.data.items

//標準的HttpWrapper
viewModelScope.launch {
    when (val result = ExceptionApiService.getService().status404()) {
        is HttpResult.Success -> {
            Log.e("Success", MoshiUtils.toJson(result.data))
        }

        is HttpResult.Failure -> {
            Log.e("Failure", result.message + "  -----  " + result.code)
        }
    }
}

在 HttpResponseCall<> 類中我們根據http 請求是否成功,4xx,5xx 分別對應處理返回HttpResult<out T : Any>中的

  • Success<T> 成功獲取期待的數據data范型T
  • Failure(msg,code) 包含了業務錯誤和Http 請求異常(timeout,networkerror)

更多請移步GitHub下載代碼查看,歡迎建議改進。

4.Moshi 解析空安全處理,默認值情況

這個情況非常多,大部分的閃退和異常源于數據的異常,比如某個必有字段沒有返回,導致異常
還有就是有些字段需要設置后端沒有返回的時候的默認值

5.LiveData 還是Flow ?

為了簡單演示,Demo 中使用的是LiveData,如果你的項目都用Kotlin 編寫了,建議遷移到Flow
從 LiveData 遷移到 Kotlin 數據流:https://juejin.cn/post/6979008878029570055

5.接入使用

參考文檔

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容