【问题标题】:Async not waiting for await异步不等待等待
【发布时间】:2017-10-09 11:23:31
【问题描述】:

我是 Kotlin 和协程的新手。但是我想用它来初始化 Android ThreeTen backport library,这是一个长期运行的任务。我正在使用 Metalab Async/Await 库 (co.metalab.asyncawait:asyncawait:1.0.0)。

这是我的代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val application = this

    async {

        //non-blocking initialize ThreeTen
        await { AndroidThreeTen.init(application) }

        //initialize UI on UI thread which uses the ThreeTen library
        initUI()

    }
}

现在我遇到初始化 UI 时库未初始化的问题。据我了解,在调用 AndroidThreeTen.init 之前不应调用 initUI

【问题讨论】:

  • 您应该先加载 UI,然后再加载数据(或在后台更早):stackoverflow.com/a/43151714/882912 否则,您在加载数据时会冻结 UI。这样你就可以显示一个进度条。

标签: android kotlin async-await kotlin-coroutines


【解决方案1】:

简短的回答是,您不应该为此使用 Kotlin 协程。

长答案是您的代码需要在初始化 UI 之前初始化 AndroidThreeTen,因此您必须等待AndroidThreeTen.init 在尝试调用之前完成initUI 无论如何。由于这种固有的等待需要,没有理由使您的代码过于复杂。协程不是魔术。他们不会以某种方式更快地等待需要大量时间的东西。 AndroidThreeTen.init 使用或不使用协程都将花费相同的时间。

你应该像这样写你的代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val application = this

    AndroidThreeTen.init(application)
    initUI()
}

【讨论】:

  • 感谢您的回答。一方面你是对的,它对性能没有任何帮助。另一方面,我仍然不明白为什么我的代码不起作用。 like here in c# 是因为 void 是不好的做法吗?
  • Metalab Async/Await 库的作者或许能够回答这个问题。如果你使用的是kotlinx.coroutines,那么你可以这样写,它会工作gist.github.com/elizarov/0b3e3386d304478368b3eb0380b6f25a
猜你喜欢
  • 2016-07-07
  • 2016-03-25
  • 2017-12-11
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 2020-10-04
相关资源
最近更新 更多