【问题标题】:Get coroutine scope reference inside anonymous inner class在匿名内部类中获取协程范围引用
【发布时间】:2020-07-06 10:52:24
【问题描述】:
  • 我正在使用 lifecycleScope 在片段内进行简单的 api 调用以获取一些数据并将其存储在 Room database 中。
  • 当我在匿名内部类中得到响应后,由于匿名内部类,我无法获得CoroutineScope 的引用来调用暂停方法。如何获取当前CoroutineScope 的引用?

演示:

lifecycleScope.launch {
    SomeClass(context).getDataFromApi( object : CallBackResult<Any> {
        override fun onSuccess(result: Any) {
           saveToLocal()   // I have to call a suspension function from here
        }
    })   
}

suspend fun saveToLocal() {
     //save some data
}

注意:我不是遵循 MVVM 模式,而是遵循 MVC。

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    您可以利用suspendCancellableCoroutine 将您的阻塞 API 调用变成一个挂起函数:

    suspend fun getDataFromApi(context: Context): Any = suspendCancellableCoroutine { continuation ->
        SomeClass(context).getDataFromApi( object : CallBackResult<Any> {
            override fun onSuccess(result: Any) {
                continuation.resume(result)
            }
        })
    }
    

    你可以这样称呼它:

    lifecycleScope.launch(Dispatchers.IO) {
        val result = getDataFromApi(context) //Here you get your API call result to use it wherever you need
        saveToLocal()
    }
    

    【讨论】:

    • 我们可以使用 async & await 方法吗?
    • @SumitShukla suspendCancellableCoroutine 就像一个“包装器”,用于阻止 API 调用以将它们转换为挂起函数。无需使用asyncawait,因为通过调用continuation.resume(...),它已经在API 响应后立即返回结果。如果您问是否可以在 async 正文中调用暂停函数以处理其结果并返回其他内容,那么可以肯定,这是完全正确的。
    • 我可以直接在 onSuccess 中使用 launch{} 吗?是不是气馁了?
    • @SumitShukla 我不会那样做有两个原因:1-我会在函数内部做不止一件事情,这会使事情复杂化。 2-测试它会很痛苦。对我来说,这已经够令人沮丧了。
    猜你喜欢
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多