3

我有一个遗留项目,我想在联系后端时使用协程。后端由 Hybris 提供的 sdk 处理。例如,它使用 volley,并带有一些回调。我想要的是用协程包装这些回调。但我遇到的问题是协程不等待完成,它启动协程,并继续下一行,方法返回一个值,然后协程完成很久。我的代码:

suspend  fun ServiceHelper.getList(): ListOfWishes {

    return suspendCancellableCoroutine { continuation ->

        getAllLists(object : ResponseReceiver<ListOfWishes> {
            override fun onResponse(response: Response<ListOfWishes>?) {
                continuation.resume(response?.data!!)

            }

            override fun onError(response: Response<ErrorList>?) {
                val throwable = Throwable(Util.getFirstErrorSafe(response?.data))
                continuation.resumeWithException(throwable)
            }
        }, RequestUtils.generateUniqueRequestId(), false, null, object : OnRequestListener {
            override fun beforeRequest() {}
            override fun afterRequestBeforeResponse() {}
            override fun afterRequest(isDataSynced: Boolean) {}
        })
    }
}

辅助方法:

suspend fun ServiceHelper.wishLists(): Deferred<ListOfWishes> {
    return async(CommonPool) {
        getWishList()
    }
}

以及调用协程的位置:

    fun getUpdatedLists(): ListOfWishes? {
    val context = Injector.getContext()
    val serviceHelper = Util.getContentServiceHelper(context) 
    var list = ListOfWishLists()
    launch(Android) {
        try {
            list = serviceHelper.wishLists().await()
        } catch (ex: Exception){
            Timber.d("Error: $ex")
        }
    }
    return list

所以不是等待serviceHelper.wishLists().await()完成,而是返回列表。我也尝试让该方法返回 a runBlocking{},但这只会阻止 UI 线程并且不会结束协程。

4

1 回答 1

0

协程不是这样工作的。getUpdatedLists()方法不能等待协程完成其执行而不是suspend方法本身。如果在or中getUpdatedLists()定义方法,您可以在执行后启动协程并在其中执行某些操作,例如更新 UI 。它看起来像这样:ActivityFragmentserviceHelper.wishLists().await()

fun loadUpdatedLists() {
    val context = Injector.getContext()
    val serviceHelper = Util.getContentServiceHelper(context) 
    lifecycleScope.launch {
        try {
            val list = serviceHelper.wishLists().await()
            // use list object, for example Update UI 
        } catch (ex: Exception){
            Timber.d("Error: $ex")
        }
    }
}

lifecycleScope-CoroutineScope绑到LifecycleOwnerLifecycle。要使用它,请添加依赖项:

androidx.lifecycle:lifecycle-runtime-ktx:2.4.0 or higher.
于 2022-02-05T20:05:30.417 回答