1、首先引入问题, 自己在转换kotlin 代码时候 重新封装了下http请求框架
1) 如何统一使用post 方法 和统一拦截
2)如何让使用者不用关心数据转换问题、不用自己声明接口方法、只专注业务
首先明确一点 使用的是 kotlin 协程来整合retrofit 结构
a、创建Http管理类 -- 创建okhttp初始化 方法、retrofit 初始化 ,apiService 初始化
这里没有什么特殊的地方
定义service 方法如下: 这里说明下 Retrofit 不支持直接使用 T 泛型引用,故不能直接在接口内直接定义泛型方法
声明返回参数 可以根据自己思路处理下,比如直接用String接收,我这边 使用定义的ResultBean 本意是通过泛型返回,我这边就懒得处理了, 主要是处理 后面封装的泛型思路
下面是实现的协程拦截方法---
private suspend fun launchGo( block: suspend CoroutineScope.() -> Unit, error: suspend CoroutineScope.(ResponseThrowable) -> Unit = { }, complete: suspend CoroutineScope.() -> Unit = {}, isShowDialog: Boolean = true ) { coroutineScope { try { block() } catch (e: Exception) { e.printStackTrace() error(ExceptionHandle.handleException(e)) } finally { complete() } } }
接下来主要是泛型实现的具体方式
通过定义泛型类型方法,同时使用泛型回调
回调变量.javaClass.genericInterfaces[0]
//获取实际泛型类型
val typeArgument = (type as ParameterizedType).actualTypeArguments[0]
这里先是通过gson 转换一个json 字符串,然后再转换成泛型类型,是因为我这因为使用的Any类型,在retrofit 返回的时候会把list 默认封装进 linktreemap 对象,在反射解析的时候会出错,所以我这边就偷懒用了这个方法
Gson().fromJson(Gson().toJson(result.data), typeArgument)
@JvmOverloads suspend fun <T> queryGet( url: String, map: HashMap<String, Any>? = null, block: (T) -> Unit, error: (String?) -> Unit = { } ) { launchGo({ val result = if (map == null) service?.getAsync(url)?.await() else service?.getAsync(url, map)?.await() val type: Type = block.javaClass.genericInterfaces[0] // 泛型的实际类型 val typeArgument = (type as ParameterizedType).actualTypeArguments[0] if (result?.errorCode?.equals("0") == true) { block.invoke(Gson().fromJson(Gson().toJson(result.data), typeArgument)) } else { error.invoke(result?.msg) } }, error = { error.invoke(it.errMsg) }) }
大体思路就是这样,后面整理好封装完后在上传git ,整体框架包括 文件上传、下载等功能封装,先记录下处理思路,先到这里。再见!!