Android-AAC架构之Kotlin协程

architecture-components-samples官方示例
在协程和 Flow 使用 LiveData

本次主要介绍第一种实现方式
本文涉及Kotlin协程,Retrofit,LiveData,ViewModel,Dagger2.Android。
在官方示例GithubBrowserSample里面没有使用协程,在实际项目里需要修改部分代码。有什么不对的地方欢迎提出。

1、Retrofit - suspend

说说这里遇到问题,加上suspend时返回类型不能是Call<T>CallAdapterFactory返回的自定义类,必须是接口返回的数据结构。下面这段代码是官方示例里面的LiveDataCallAdapterFactoryLiveDataCallAdapter返回一个LiveData<T>,在CallAdapter.Factory里面会自动加上一个Calll<T>,返回LiveData<T>会报类型转换异常,因为responseTypeCall<T>并不是LiveData<T>
JakeWharton回复:https://github.com/square/retrofit/issues/3246

@POST(API.LOGIN)
suspend fun login(@Body any: Any): LiveData<Result<User>>

class LiveDataCallAdapterFactory : Factory() {
   
    override fun get(
        returnType: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
   
        if (getRawType(returnType) != LiveData::class.java) {
   
            return null
        }
        val observableType = getParameterUpperBound(0, returnType as ParameterizedType)
        val rawObservableType = getRawType(observableType)
        if (rawObservableType != ApiResponse::class.java) {
   
            throw IllegalArgumentException("type must be a resource")
        }
        if (observableType !is ParameterizedType) {
   
            throw IllegalArgumentException("resource must be parameterized")
        }
        val bodyType = getParameterUpperBound(0, observableType)
        return LiveDataCallAdapter<Any>(bodyType)
    }
}

class LiveDataCallAdapter<R>(private val responseType: Type) :
    CallAdapter<R, LiveData<ApiResponse<R>>> {
   

    override fun responseType() = responseType

    override fun adapt(call: Call<R>): LiveData<ApiResponse<R>> {
   
        return object : LiveData<ApiResponse<R>>() {
   
            private var started = AtomicBoolean(false)
            override fun onActive() {
   
                super.onActive()
                if (started.compareAndSet(false, true)) {
   
                    call.enqueue(object : Callback<R> {
   
                        override fun onResponse(call: Call<R>, response: Response<R>) {
   
                            postValue(ApiResponse.create(response))
                        }

                        override fun onFailure(call: Call<R>, throwable: Throwable) {
   
                            postValue(ApiResponse.create(throwable))
                        }
                    })
                }
            }
        }
    }
}

换成Call<T>会导致GsonConverterFactory报错。

@POST(API.LOGIN)
suspend fun login(@Body any: Any): Call<Result<User>>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值