浅谈Kotlin 下封装统一的 Retrofit 泛型问题

本文介绍了如何使用Kotlin协程重构Retrofit框架,实现统一的POST请求和错误拦截,以及如何让开发者专注于业务逻辑,通过泛型处理数据转换。作者详细展示了创建Http管理类、协程拦截方法和泛型API调用的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 ,整体框架包括 文件上传、下载等功能封装,先记录下处理思路,先到这里。再见!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值