可以根据
返回值类型
,区分响应规则
的,kotlin携程
网络库
- 多部门,多规则,每个部门有每个部门的网络请求规则。返回值内容、规则都不同。
- 多模块,多规则,每个模块可使用一个或多个规则。
- 公司目前只有一个规则,但不保证后续没新增。
project build.gradle
allprojects {
repositories {
mavenCentral()
}
}
app build.gradle
implementation 'io.github.zrq1060:retrofit-adapter:0.0.1'
Retrofit.Builder()
.addCallAdapterFactory(CoroutinesResponseCallAdapterFactory.create())
.build()
/**
* 获取用户信息
*/
@GET("getUser")
suspend fun getUser(): ApiResponse<XXX<User>>
XXX
为公司网络请求规则通用包装类:如规定,会返回code
、message
、data
。且当code
为200
时代表成功,其它代表失败并提示message
。则XXX
可以为:
data class BaseData<T>(val code: Int?, val message: String?, val data: T?)
则网络请求接口定义为:
/**
* 获取用户信息
*/
@GET("getUser")
suspend fun getUser(): ApiResponse<BaseData<User>>
声明规则,使其对返回值类型
为XXX
的网络响应结果进行处理,如以上面的例子为例,BaseData
作为返回值类型
,进行处理,代码如下(!!!看代码注释):
例子规则:
网络成功
并且code为200
并且data不为空
,则代表成功(Success
)。网络成功
并且code不为200
,则代表失败(Error
)。网络失败
、ResponseCode失败
、ResponseBody为空
等,则代表异常(Exception
)。
创建自定义类,实现ApiResponseResultHandler
接口。
class BaseDataApiResponseResultHandler : ApiResponseResultHandler {
/**
* 优先级,值越大优先级越高越优先处理,值相同按先添加的先判断。
*/
override fun priority(): Int {
return 0
}
/**
* 此处理器,是否处理此返回值类型,如果返回为true,则会调用
* [handleOnResponse]、[handleOnFailure]进行后续处理。
*/
override fun shouldHandle(resultClass: Class<*>): Boolean {
return resultClass == BaseData::class.java
}
/**
* 处理网络请求-响应结果
*/
override fun <T> handleOnResponse(response: Response<T>): ApiResponse<T> {
return if (response.isSuccessful) {
// 网络成功
val body = response.body()
if (body != null) {
// body不为空
val baseData = body as BaseData<*>
val baseDataCode = baseData.code
if (baseDataCode == null) {
// 公司code规则异常
ApiResponse.exception(RulesException("BaseData code is null"))
} else if (baseDataCode == 200) {
// 公司code规则成功
val data = baseData.data
if (data != null) {
// 公司data规则成功
ApiResponse.success(body)
} else {
// 公司data规则异常
ApiResponse.exception(RulesException("BaseData data is null"))
}
} else {
// 公司code规则失败
ApiResponse.error(baseDataCode, baseData.message ?: "")
}
} else {
// body为空
ApiResponse.exception(ResponseBodyEmptyException())
}
} else {
// 网络失败
ApiResponse.exception(ResponseCodeErrorException(response.code()))
}
}
/**
* 处理网络请求-失败结果
*/
override fun <T> handleOnFailure(t: Throwable): ApiResponse<T> {
return ApiResponse.exception(t)
}
}
说明:
ApiResponse
为API
响应类。含有子类Success
、Error
、Exception
三种结果。 分别代表着成功、失败、异常。
在网络请求前添加规则,如在Application
添加。
class App : Application() {
override fun onCreate() {
super.onCreate()
// 增加自定义规则
ApiResponseHandlerManager
.add(BaseDataApiResponseResultHandler())
// .add(OtherApiResponseResultHandler())
}
}
说明:
ApiResponseHandlerManager
可添加多个ApiResponseResultHandler
。如果优先级相同,则先添加的,先判断。- 如果没有符合返回值类型的规则,则默认网络成功代表成功,网络失败代表失败。
viewModelScope.launch {
api.getUser()
.onSuccess {
// 成功,此方法内可直接拿到-成功数据data
}.onFailure {
// 失败,包含下面的Error、Exception。
}.onError {
// 失败-错误,此方法内可直接拿到-code、message
}.onException {
// 失败-异常,此方法内可直接拿到-throwable
}
}
viewModelScope.launch {
when (val result = api.getUser()) {
is ApiResponse.Success -> {
// 成功,可通过result拿到-成功数据data
}
is ApiResponse.Failure -> {
// 失败,包含下面的Error、Exception。
}
is ApiResponse.Failure.Error -> {
// 失败-错误,可通过result拿到-code、message
}
is ApiResponse.Failure.Exception -> {
// 失败-异常,可通过result拿到-throwable
}
}
}
上面是根据返回值类型,去获取对应添加的处理逻辑,具有通用性。此为在指定的网络请求接口定义上标注ApiResponseHandler
注解,以指定规则,具有特定性。
如以上面的例子为例,之前是code为200
代表成功,现在改成为code为0
代表成功,进行处理,代码如下:
创建自定义类,实现ApiResponseAnnotationHandler
接口。
class BaseDataApiResponseAnnotationHandler : ApiResponseAnnotationHandler {
/**
* 处理网络请求-响应结果
*/
override fun <T> handleOnResponse(response: Response<T>): ApiResponse<T> {
return if (response.isSuccessful) {
// 网络成功
val body = response.body()
if (body != null) {
// body不为空
val baseData = body as BaseData<*>
val baseDataCode = baseData.code
if (baseDataCode == null) {
// 公司code规则异常
ApiResponse.exception(RulesException("BaseData code is null"))
} else if (baseDataCode == 0) {
// 公司code规则成功
val data = baseData.data
if (data != null) {
// 公司data规则成功
ApiResponse.success(body)
} else {
// 公司data规则异常
ApiResponse.exception(RulesException("BaseData data is null"))
}
} else {
// 公司code规则失败
ApiResponse.error(baseDataCode, baseData.message ?: "")
}
} else {
// body为空
ApiResponse.exception(ResponseBodyEmptyException())
}
} else {
// 网络失败
ApiResponse.exception(ResponseCodeErrorException(response.code()))
}
}
/**
* 处理网络请求-失败结果
*/
override fun <T> handleOnFailure(t: Throwable): ApiResponse<T> {
return ApiResponse.exception(t)
}
}
说明:
ApiResponseAnnotationHandler
接口比ApiResponseResultHandler
接口少priority()
、shouldHandle(resultClass)
这两个方法,因为能知道它作用在哪个网络请求接口,所以不需要再进行匹配(shouldHandle(resultClass)
方法完成)和解决多个匹配问题(priority()
方法完成)。
在指定的网络请求接口定义上标注ApiResponseHandler
注解,并指定创建的规则(如:BaseDataApiResponseAnnotationHandler
)。
/**
* 获取用户信息
*/
@GET("getUser")
@ApiResponseHandler(BaseDataApiResponseAnnotationHandler::class)
suspend fun getUser(): ApiResponse<BaseData<User>>
说明:
- 指定规则,不需要添加到
ApiResponseHandlerManager
中。- 如果有指定规则,则以指定规则为主,添加规则的则无效。
QQ:273902141
QQ群:644493632