【问题标题】:Difference between launchWhenStarted and repeatOnLifecycle(STARTED) in collecting flowslaunchWhenStarted 和 repeatOnLifecycle(STARTED) 收集流的区别
【发布时间】:2022-06-24 06:05:13
【问题描述】:

如果新 API 的名称相似(例如,使用 launchWhenever 作为重新启动 API),开发人员可能会感到困惑,甚至在不注意的情况下互换使用它们。

source

什么时候使用哪个更简单的解释?

【问题讨论】:

  • launchWhenStarted suspends the execution of the coroutine, and repeatOnLifecycle cancels and restarts a new coroutine 这就是区别。如果您有一个使用lauchWhen... 启动的正在运行的协程并且生命周期低于该级别,则协程将被挂起(但仍会处于活动状态,因此取决于它所做的其他事情,您可能会在不需要的事情上浪费资源)。较新的repeatOn... 更“聪明”,因为它可以取消协程并在需要时启动新的协程。看到这一点的最简单方法是自己尝试。

标签: android kotlin kotlin-flow


【解决方案1】:

launchWhenStarted 只是一个时间延迟。

repeatOnLifecycle 创建一个挂起点,作为处理程序,每次生命周期进入提供的状态时运行提供的块,并在低于它时取消它(因此对于STARTED,它在停止时发生)。

【讨论】:

    【解决方案2】:

    repeatOnLifecycle 在每次重复时从头开始重新启动协程,并在每次生命周期低于指定状态时取消协程。它非常适合收集大多数流,因为它会在不需要时完全取消流,从而节省与流继续发出值相关的资源。

    launchWhenX 不会取消协程并重新启动它。它只是在启动时推迟,并在低于指定状态时暂停执行。他们计划弃用这些函数,但我怀疑如果他们这样做了,就需要进行一些替换,因为你正在调用一些耗时的挂起函数,然后想要在它完成后做一些事情,比如启动一个片段事务。为此使用repeatOnLifecycle 会导致重做耗时的操作。

    【讨论】:

    • "适用于您正在调用一些耗时的挂起函数,然后在它完成后想要做一些事情的情况,比如开始一个片段事务。"在这种情况下使用 SharedFlow 会更好吗?
    • @ghiath,可能是这样,但如果 Jetpack 库期望你在所有事情上都使用 Flows,那就太自以为是了。
    【解决方案3】:

    channel 支持的冷流或使用带有缓冲区的运算符(例如bufferconflateflowOnshareIn不安全收集现有的 API,例如 CoroutineScope.launchFlow<T>.launchInLifecycleCoroutineScope.launchWhenX,除非您手动取消在活动进入后台时启动协程的 Job。这些 API 将保持底层流生产者处于活动状态,同时在后台将项目发送到缓冲区中,从而浪费资源。

    要使用这些 API 解决这个问题,您需要在视图进入后台时手动取消收集。但这听起来像是一个样板代码。

    这就是 Google 推荐 repeatOnLifecycle(Lifecycle.State.XXX) 以使其简单安全的原因。

    repeatOnLifecycle 是一个挂起函数,它以Lifecycle.State 作为参数,用于自动创建和启动一个新的协程,当生命周期到达@987654334 时将块传递给它@,并且当生命周期低于状态时,取消正在执行块的正在进行的协程

    通过here了解更多信息

    【讨论】:

      猜你喜欢
      • 2021-12-27
      • 2017-12-27
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 2015-03-14
      • 2012-06-17
      • 1970-01-01
      • 2012-03-16
      相关资源
      最近更新 更多