首页 > 解决方案 > Coroutines:在特定的 CoroutineContext 上运行 Deferred

问题描述

我正在尝试在 Android 应用程序中使用 Kotlin Coroutines,特别是我已经为 Retrofit 导入了 Kotlin Coroutine Adapter

Kotlin Coroutine Adapter 将 Retrofit 接口更改为返回 aDeferred<T>而不是Call<T>.

我不明白的是如何以我想要Deferred的特定方式启动它。CoroutineContext考虑以下代码:


    class MyViewModel @Inject constructor(
        private val foo: Foo,
        @Named("ui") private val uiContext: CoroutineContext,
        @Named("network") private val networkContext: CoroutineContext
    ) : ViewModel() {

      fun performSomeJob(param: String) {
          launch(uiContext) {
            try {
              val response = foo.bar(param).await()
              myTextView.setText(response.name)
            } catch (error: Throwable) {
              Log.e(error)
            }
          }
    }

在哪里foo.bar(param)返回Deferred<SomeModel>

CoroutineContext此代码有效,但我不确定foo.bar(param)正在执行什么(CommonPool??)。

如何明确指定我想foo.bar(param)在 a 中执行networkContext


    val response = async(networkContext) { foo.bar(param) }.await()

这段代码不起作用,因为response被评估为Deferred<SomeModel>而不是SomeModel(我想要实现)。

标签: androidkotlinretrofitretrofit2kotlin-coroutines

解决方案


foo.bar()调用不会启动另一个协程,它只是包装本机 RetrofitCall以便其状态更改传播到Deferred. Retrofit 管理自己的线程来执行它的操作,这就像没有协程包装器一样工作。如果你有一个特定的问题,你可以通过以通常的方式配置 Retrofit 来管理它。

对你来说唯一重要的是你的协程是在 UI 上下文中执行的。


推荐阅读