<meta charset="utf-8">
框架简介
Lotus 网络库基于 Retrofit 进行封装,Retrofit是Square公司开源的网络框架,底层是基于 OkHttp 实现的,不过相比 OkHttp 使用更方便,更适合进行 RESTful API 格式的请求。
网络库内部实现了 Lotus 双向认证功能,可以在初始化的时候选择是否开启双向认证,框架会自动切换对应的url,业务方无需关注和服务端的认证细节。
快速上手
网络库中默认打开了双向认证,并根据双向认证开关配置了相应的 baseUrl,大多数场景下只需要控制双向认证开关,其余配置走默认即可。
-
初始化
在发起网络请求之前(建议在Application
的onCreate()
中),调用:
RetrofitController.init(application, enableMutualAuth)
-
application:Application类型,传入当前App的Application实例
-
enableMutualAuth:Boolean类型,双向认证开关
在调用了init之后就完成了初始化工作,内部包含了双向认证、网络状态、本地网络缓存等等功能,所有的网络请求都需要在初始化之后发起。
-
定义数据 Model
在请求之前需要根据接口协议的字段定义对应的数据Model,用来做Request或者Request的body。
比如我们需要通过UserId获取对应用户的UserName
-
定义 Request 数据 Model
后端请求接口参数如下:
{
"userId" : "123456"
}
那么根据参数定义一个UserNameReq类:
data class UserNameReq(
/** 用户id */
var userId: String
)
-
定义 Response 数据 Model
后端返回数据如下:
{
"userName" : "MC"
}
对应定义一个UserNameReq:
data class UserNameRsp(
/** 用户id */
var userId: String
)
-
编写 Http 接口
用注解的形式标注 Http 方法,然后参数传入 http 请求的 url:
/** 获取用户ID */
@POST("api/cloudxcar/atmos/v1/getName")
suspend fun getUserName(@Body request: UserNameReqesponseEntity<UserNameRsp>
返回是一个 Response 实体,内部包含服务端的返回码、提示信息及返回数据。
-
实现具体请求类
suspend fun getUserName(userId: String = ""): ResponseEntity<UserNameRsp> {
val responseEntity = withTimeoutOrNull(TIME_OUT) {
withContext(Dispatchers.IO) {
RetrofitController.client.getUserName(
UserNameReq(userId)
)
}
}
return responseEntity
}
请求类主要做的事就是调用网络接口,然后返回响应实体
-
发起请求并处理返回结果
网络库定义了一个顶层函数用来发起请求并接收返回结果或处理异常:
fun <reified T> httpRequest(block, fail, error, cacheKey): T?
-
block:实际请求体,必填。可以传入步骤 4 中实现的接口
-
fail:请求错误回调,非必填。用来处理服务端返回的请求错误,会携带错误码及错误信息
-
error:请求异常回调,非必填。用来处理请求中发生的异常,此时没有response返回
-
cacheKey:数据缓存唯一标识,非必填
httpRequest 中的泛型 T 就是步骤2定义的 Response 实体,正常返回会在方法内部自动解析出 UserNameRsp
,到此就完成了一次网络请求。
设置配置项
-
设置双向认证开关
在初始化的时候控制双向认证开关:
fun init(context: Application, needMutualAuth: Boolean = true)
方法内部会根据开关值来切换不同的后端服务器
-
替换 BaseUrl
在网络库内部预置了 Lotus 的后端Host地址:
两个分别对应带双向认证的接口和不带双向认证的接口,大多数App可以直接使用这两个 host 作为BaseUrl 完成网络请求。
网络库内部封装了一个 OKHttp client,默认使用了以上 url 作为 BaseUrl,同时网络库支持配置自定义的 BaseUrl,可使用以下接口重新获取一个新的Client:
fun obtainClient(baseUrl: String, mutualAuthenticate: Boolean = true): ServerApi
传入自定义 BaseUrl 及双向认证开关即可,后续网络请求使用新的Client即可。
-
数据缓存
在前面发起请求调用httpRequest
顶层函数的时候,可以传入一个可选参数cacheKey
,这个key不为空则网络库会在本地保存当前请求的返回数据。Key作为缓存的唯一标识,在无网络或请求失败的时候,会通知调用方错误,并返回缓存的数据。
缓存部分流程如下:
image.png
-
错误及异常处理
在发起请求的顶层函数 httpRequest
中,有两个参数用来提供给调用方处理错误和异常。
首先区分一下错误和异常:
错误通常是发起了网络请求,且网络请求有响应,只是由于接口地址或者参数等等原因导致服务端解析失败,最终返回错误码及错误信息。
而异常是指在发起网络请求的过程中出现了 Exception,导致整个网络请求流程被中断,所以当异常发生的时候,网络库是不会返回错误码和错误信息的,只能返回异常信息供调用方定位问题。
回调的使用方式很简单,只需要在httpRequest
中传入两个回调:fail
和error
,下面分别看看二者的处理方式:
-
错误处理
fai的定义如下:
fail: (response: ResponseEntity<T>) -> Unit = {
onFail(it)
}
传入的回调有一个 ResponseEntity 参数,这是网络请求返回的响应实体,内部包含errorCode
和errorMessage
,不传则默认打印这两个字段,可以在 Logcat 中通过Tag:Http Request
过滤出来。
-
异常处理
error的定义如下:
error: (e: Exception) -> Unit = {
onError(it)
},
回调函数只有一个 Exeption 对象,和前面的定义相符,在异常的时候将异常返回供调用方定位问题。不传网络库默认打印异常,可以在 Logcat 中通过Tag:Http Request
过滤出来。
网友评论