协程+Retrofit2.4封装一个网络请求框架

        好久没写博客了,最近也是比较忙,新项目使用了协程和Retrofit2.6,开发过程中发现了Retrofit2.6上传文件不支持中文名称,排查发现是其Okhttp新版本不支持,只能降低Retorfit版本了,低版本的Retrofit也不支持协程了,需要自己封装一下,今天就记录一下封装方法以及使用。

添加项目依赖,新项目还用到了lifecycle

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'org.ligboy.retrofit2:converter-fastjson-android:2.1.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.0.0'、
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"

定义基础数据返回类

@NoArgOpenDataClass
data class BaseResp<T>(var code: Int=0, var description: String?, var data: T?){
}

为了能像RxJava那种链式展示,我自定义了用于请求的DSL样式

class HttpRequestDsl<T : BaseResp<*>>() {

    //协程作用域
    lateinit var scope: CoroutineScope
    //请求响应
    lateinit var response: Response<T?>
    internal var onSuccess: ((T) -> Unit)? = null
    internal var onComplete: (() -> Unit)? = null
    internal var onError: ((Exception) -> Unit)? = null

    fun onSuccess(onSuccess: ((T) -> Unit)?) {
        this.onSuccess = onSuccess
    }

    fun onComplete(onComplete: (() -> Unit)) {
        this.onComplete = onComplete
    }

    fun onError(onError: ((Exception) -> Unit)?) {
        this.onError = onError
    }
}

在顶层文件中定义一个通用的请求方法

fun <T : BaseResp<*>> requestApi(
    scope: CoroutineScope,
    request: suspend CoroutineScope.() -> Call<T?>,
    dsl: HttpRequestDsl<T>.() -> Unit
): Job {
    return scope.launch {
        val httpRequestDsl = HttpRequestDsl<T>()
        try {
            httpRequestDsl.scope = scope
            withContext(Dispatchers.IO) {
                //dsl主要是对onSuccess、onComplete和onError赋值
                httpRequestDsl.dsl()
                //执行request区域方法,并赋值response
                httpRequestDsl.response = request.invoke(scope).execute()
            }
            if (httpRequestDsl.response.isSuccessful) {
                val body = httpRequestDsl.response.body()
                if (body != null) {
                    httpRequestDsl.onSuccess?.invoke(body)
                    httpRequestDsl.onComplete?.invoke()
                } else {
                    httpRequestDsl.onError?.invoke(HttpException(httpRequestDsl.response))
                }
            } else {
                val httpException = HttpException(httpRequestDsl.response)
                httpRequestDsl.onError?.invoke(httpException)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            if (!(e is CancellationException)) {
                httpRequestDsl.onError?.invoke(e)
            }
        }
    }
}

扩展ViewModel类,添加一个requestApi方法

fun <T : BaseResp<*>> ViewModel.requestApi(
    request: suspend CoroutineScope.() -> Call<T?>,
    dsl: HttpRequestDsl<T>.() -> Unit
): Job {
    return requestApi(this.viewModelScope, request, dsl)
}

工具简单封装好了,接下来就可以使用啦

定义一个请求接口类

interface UserPost {
    @POST("/app/Login")
    fun login(@Body body: RequestBody?): Call<BaseResp<LoginData>?>
}

在需要网络请求的地方使用

requestApi({
    val request = LoginRequest()
    RetrofitManager.instance.create<UserPost>().login(
        instance.getRequestBodyByObject(request)
    )
}, {
    onSuccess {
        ……
    }
    onError {
        ……
    }
    onComplete {
        ……
    }
})

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值