【问题标题】:How to retry API call in retrofit interface with coroutines enabled如何在启用协程的改造接口中重试 API 调用
【发布时间】:2021-08-05 22:16:07
【问题描述】:

每当在 API 调用中发生 Internet 丢失或未知错误等一般错误时,我有一个用例需要显示带有重试按钮的错误 UI。当用户按下重试之前失败的 API 应该调用并恢复用户流程。

迁移协程方法前的API接口:

 interface TodoService {
    @POST("todo/create")
   fun createTodo(@Body request: TodoRequest): Call<TodoResponse>
}

API 客户端:

    fun <T> fetch(call: Call<T>, completion: (result: NetworkBoundResource<T>) -> Unit) {
   
    call.enqueue(object : Callback<T> {
        override fun onFailure(call: Call<T>, t: Throwable) {
            // I have the mechanism save call object and completion and show error UI
            // when user press retry fetch(call.clone(), completion
        }

        override fun onResponse(call: Call<T>, response: Response<T>) {

        }
    })
}

在将改造接口迁移到协程挂起方法之前,这不是问题。因为我可以克隆改造调用对象(call.clone()) 并按照代码 cmets 中的说明重试 API 调用。

协程方法迁移后的API接口:

interface TodoService {
   @POST("todo/create")
   suspend fun createTodo(@Body request: TodoRequest): TodoResponse
}

现在如何在没有 Call 对象的情况下实现相同的功能?

【问题讨论】:

    标签: android kotlin retrofit2 kotlin-coroutines


    【解决方案1】:

    您可以通过将操作保存在协程作业之外来处理重试 e. G。在按钮上添加调度。

    这是一个简单的例子,但没有完成:

    class ViewModel {
    
        val context = CoroutineScope(Dispatchers.Main)
        var dispatchRetry: (() -> Unit)? = null
    
        fun createTodo(requestData: TodoRequest) {
            context.launch() {
                try {
                    todoService.createTodo(requestData)
                } catch (t: Throwable) {
                    dispatchRetry = { todoService.createTodo(requestData) }
                }
            }
        }
    
        fun retry() {
            dispatchRetry?.invoke()
        }
    }
    

    【讨论】:

    • 这个解决方案很有帮助。但我必须处理每个 ViewModel。所以解决方案不可扩展。
    • 如果您只有几个请求,我会采用非通用解决方案(遵循 KISS)。但是您也可以创建自己的包装器,它通过重试处理每个协程执行。
    【解决方案2】:

    使用存储库和视图模型使用协程通过实时数据获取响应,然后在您的活动中用户观察者获取日期这是使用协程的最佳方式,也是 MVVM 的最佳实践

    【讨论】:

    • 我遵循存储库模式。看来你没明白我的问题。我不使用改造 Call 因为如果你暂停它是没有必要的。现在如何重试?
    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2018-06-13
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 2016-09-22
    相关资源
    最近更新 更多