<meta charset="utf-8">
框架簡介
Lotus 網(wǎng)絡(luò)庫基于 Retrofit 進(jìn)行封裝,Retrofit是Square公司開源的網(wǎng)絡(luò)框架,底層是基于 OkHttp 實(shí)現(xiàn)的,不過相比 OkHttp 使用更方便,更適合進(jìn)行 RESTful API 格式的請求。
網(wǎng)絡(luò)庫內(nèi)部實(shí)現(xiàn)了 Lotus 雙向認(rèn)證功能,可以在初始化的時(shí)候選擇是否開啟雙向認(rèn)證,框架會(huì)自動(dòng)切換對應(yīng)的url,業(yè)務(wù)方無需關(guān)注和服務(wù)端的認(rèn)證細(xì)節(jié)。
快速上手
網(wǎng)絡(luò)庫中默認(rèn)打開了雙向認(rèn)證,并根據(jù)雙向認(rèn)證開關(guān)配置了相應(yīng)的 baseUrl,大多數(shù)場景下只需要控制雙向認(rèn)證開關(guān),其余配置走默認(rèn)即可。
-
初始化
在發(fā)起網(wǎng)絡(luò)請求之前(建議在Application的onCreate()中),調(diào)用:
RetrofitController.init(application, enableMutualAuth)
application:Application類型,傳入當(dāng)前App的Application實(shí)例
enableMutualAuth:Boolean類型,雙向認(rèn)證開關(guān)
在調(diào)用了init之后就完成了初始化工作,內(nèi)部包含了雙向認(rèn)證、網(wǎng)絡(luò)狀態(tài)、本地網(wǎng)絡(luò)緩存等等功能,所有的網(wǎng)絡(luò)請求都需要在初始化之后發(fā)起。
-
定義數(shù)據(jù) Model
在請求之前需要根據(jù)接口協(xié)議的字段定義對應(yīng)的數(shù)據(jù)Model,用來做Request或者Request的body。
比如我們需要通過UserId獲取對應(yīng)用戶的UserName
-
定義 Request 數(shù)據(jù) Model
后端請求接口參數(shù)如下:
{
"userId" : "123456"
}
那么根據(jù)參數(shù)定義一個(gè)UserNameReq類:
data class UserNameReq(
/** 用戶id */
var userId: String
)
-
定義 Response 數(shù)據(jù) Model
后端返回?cái)?shù)據(jù)如下:
{
"userName" : "MC"
}
對應(yīng)定義一個(gè)UserNameReq:
data class UserNameRsp(
/** 用戶id */
var userId: String
)
-
編寫 Http 接口
用注解的形式標(biāo)注 Http 方法,然后參數(shù)傳入 http 請求的 url:
/** 獲取用戶ID */
@POST("api/cloudxcar/atmos/v1/getName")
suspend fun getUserName(@Body request: UserNameReqesponseEntity<UserNameRsp>
返回是一個(gè) Response 實(shí)體,內(nèi)部包含服務(wù)端的返回碼、提示信息及返回?cái)?shù)據(jù)。
-
實(shí)現(xiàn)具體請求類
suspend fun getUserName(userId: String = ""): ResponseEntity<UserNameRsp> {
val responseEntity = withTimeoutOrNull(TIME_OUT) {
withContext(Dispatchers.IO) {
RetrofitController.client.getUserName(
UserNameReq(userId)
)
}
}
return responseEntity
}
請求類主要做的事就是調(diào)用網(wǎng)絡(luò)接口,然后返回響應(yīng)實(shí)體
-
發(fā)起請求并處理返回結(jié)果
網(wǎng)絡(luò)庫定義了一個(gè)頂層函數(shù)用來發(fā)起請求并接收返回結(jié)果或處理異常:
fun <reified T> httpRequest(block, fail, error, cacheKey): T?
block:實(shí)際請求體,必填??梢詡魅氩襟E 4 中實(shí)現(xiàn)的接口
fail:請求錯(cuò)誤回調(diào),非必填。用來處理服務(wù)端返回的請求錯(cuò)誤,會(huì)攜帶錯(cuò)誤碼及錯(cuò)誤信息
error:請求異常回調(diào),非必填。用來處理請求中發(fā)生的異常,此時(shí)沒有response返回
cacheKey:數(shù)據(jù)緩存唯一標(biāo)識(shí),非必填
httpRequest 中的泛型 T 就是步驟2定義的 Response 實(shí)體,正常返回會(huì)在方法內(nèi)部自動(dòng)解析出 UserNameRsp,到此就完成了一次網(wǎng)絡(luò)請求。
設(shè)置配置項(xiàng)
-
設(shè)置雙向認(rèn)證開關(guān)
在初始化的時(shí)候控制雙向認(rèn)證開關(guān):
fun init(context: Application, needMutualAuth: Boolean = true)
方法內(nèi)部會(huì)根據(jù)開關(guān)值來切換不同的后端服務(wù)器
-
替換 BaseUrl
在網(wǎng)絡(luò)庫內(nèi)部預(yù)置了 Lotus 的后端Host地址:
兩個(gè)分別對應(yīng)帶雙向認(rèn)證的接口和不帶雙向認(rèn)證的接口,大多數(shù)App可以直接使用這兩個(gè) host 作為BaseUrl 完成網(wǎng)絡(luò)請求。
網(wǎng)絡(luò)庫內(nèi)部封裝了一個(gè) OKHttp client,默認(rèn)使用了以上 url 作為 BaseUrl,同時(shí)網(wǎng)絡(luò)庫支持配置自定義的 BaseUrl,可使用以下接口重新獲取一個(gè)新的Client:
fun obtainClient(baseUrl: String, mutualAuthenticate: Boolean = true): ServerApi
傳入自定義 BaseUrl 及雙向認(rèn)證開關(guān)即可,后續(xù)網(wǎng)絡(luò)請求使用新的Client即可。
-
數(shù)據(jù)緩存
在前面發(fā)起請求調(diào)用httpRequest頂層函數(shù)的時(shí)候,可以傳入一個(gè)可選參數(shù)cacheKey,這個(gè)key不為空則網(wǎng)絡(luò)庫會(huì)在本地保存當(dāng)前請求的返回?cái)?shù)據(jù)。Key作為緩存的唯一標(biāo)識(shí),在無網(wǎng)絡(luò)或請求失敗的時(shí)候,會(huì)通知調(diào)用方錯(cuò)誤,并返回緩存的數(shù)據(jù)。
緩存部分流程如下:

-
錯(cuò)誤及異常處理
在發(fā)起請求的頂層函數(shù) httpRequest 中,有兩個(gè)參數(shù)用來提供給調(diào)用方處理錯(cuò)誤和異常。
首先區(qū)分一下錯(cuò)誤和異常:
錯(cuò)誤通常是發(fā)起了網(wǎng)絡(luò)請求,且網(wǎng)絡(luò)請求有響應(yīng),只是由于接口地址或者參數(shù)等等原因?qū)е路?wù)端解析失敗,最終返回錯(cuò)誤碼及錯(cuò)誤信息。
而異常是指在發(fā)起網(wǎng)絡(luò)請求的過程中出現(xiàn)了 Exception,導(dǎo)致整個(gè)網(wǎng)絡(luò)請求流程被中斷,所以當(dāng)異常發(fā)生的時(shí)候,網(wǎng)絡(luò)庫是不會(huì)返回錯(cuò)誤碼和錯(cuò)誤信息的,只能返回異常信息供調(diào)用方定位問題。
回調(diào)的使用方式很簡單,只需要在httpRequest中傳入兩個(gè)回調(diào):fail和error,下面分別看看二者的處理方式:
-
錯(cuò)誤處理
fai的定義如下:
fail: (response: ResponseEntity<T>) -> Unit = {
onFail(it)
}
傳入的回調(diào)有一個(gè) ResponseEntity 參數(shù),這是網(wǎng)絡(luò)請求返回的響應(yīng)實(shí)體,內(nèi)部包含errorCode和errorMessage,不傳則默認(rèn)打印這兩個(gè)字段,可以在 Logcat 中通過Tag:Http Request過濾出來。
-
異常處理
error的定義如下:
error: (e: Exception) -> Unit = {
onError(it)
},
回調(diào)函數(shù)只有一個(gè) Exeption 對象,和前面的定義相符,在異常的時(shí)候?qū)惓7祷毓┱{(diào)用方定位問題。不傳網(wǎng)絡(luò)庫默認(rèn)打印異常,可以在 Logcat 中通過Tag:Http Request過濾出來。