【问题标题】:Effect of using GlobalScope.launch while using coroutine使用协程时使用 GlobalScope.launch 的效果
【发布时间】:2021-11-21 14:25:13
【问题描述】:

1.

我正在使用:

override fun updateNotification(mediaSession: MediaSessionCompat) {
    if (!PlayerService.IS_RUNNING) return
    GlobalScope.launch {
        notificationManager.notify(NOTIFICATION_ID, buildNotification(mediaSession))
    }
}

我可以使用:

 override fun updateNotification(mediaSession: MediaSessionCompat) {
    if (!BeatPlayerService.IS_RUNNING) return
    CoroutineScope(Dispatchers.IO).launch {
        notificationManager.notify(NOTIFICATION_ID, buildNotification(mediaSession))
    }
}

2.

我正在使用:

GlobalScope.launch {
  while (true) {
  delay(100)
  mediaMediaConnection.mediaController ?: continue
  val newTime = mediaMediaConnection.mediaController?.playbackState?.position
  if (state == BIND_STATE_BOUND) newTime?.toInt()?.let { update(it) }
  if (state == BIND_STATE_CANCELED) break
     }
  }

我可以使用:

 CoroutineScope(Dispatchers.IO).launch {
        while (true) {
            delay(100)
            mediaMediaConnection.mediaController ?: continue
            val newTime = mediaMediaConnection.mediaController?.playbackState?.position
            if (state == BIND_STATE_BOUND) newTime?.toInt()?.let { update(it) }
            if (state == BIND_STATE_CANCELED) break
        }
    }

在我的音乐应用中使用 GlobalScope.launchCoroutineScope().launch 时,我没有发现任何明显的差异。

谁能解释一下在我的1和2

的上下文中哪个更好用

我见过:

Why not use GlobalScope.launch?

但不太了解,尤其是在我的用例中。

【问题讨论】:

  • 你在哪里有这个第二个代码?在活动/服务中?
  • 不,在 viewModel @ArpitShukla

标签: android android-studio kotlin kotlin-coroutines


【解决方案1】:

有人能解释一下在我的 1 和 2 的上下文中使用哪个更好

两者都没有。

它们的问题在于它们几乎不受约束。他们不尊重应用程序的生命周期,这意味着如果您的应用程序关闭(或用户离开该屏幕)而某些协程在这些范围内运行,它们将不会停止执行并且会泄漏协程(应用程序甚至可能崩溃)

我的应用程序何时会崩溃:

GlobalScope.launch {
    fetchUserData() // --> this is a suspend function
    updateUI() // e.g. progressBar.isVisible = false
}

如果用户在fetchUserData 被挂起时离开屏幕。然后该代码不会停止执行,当fetchUserData 返回时,它会尝试更新 UI,但由于屏幕已更改,它将引发异常并且您的应用程序将崩溃。

我们想要的是协程在不再需要时停止。如果您使用GlobalScope,您将失去所有控制权。对于自定义CoroutineScope,如果您在正确的时间取消它,一切都很好,否则它也是有害的。

还有什么选择?
您可以/应该使用 android 提供的内置范围,例如 lifecycleScopeviewModelScope。第一个跟随活动(或片段)的生命周期,而第二个在视图模型被销毁时被清理。

所以,这是一般建议。针对您的具体情况,

  • 在第一种情况下,您甚至不需要协程作用域,因为 notify 是一个非常简单的函数(既不挂起也不阻塞)
  • 在第二种情况下,您有一个无限循环,当满足特定条件时会中断。由于您在 ViewModel 中有此代码,因此您很可能不希望它在视图模型被清除后运行。如果您使用CoroutineScope()GlobalScope,您将无法控制它。因此,您应该在此处使用viewModelScope,以便在不再需要工作时停止无限循环。

【讨论】:

  • 完美答案!谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-07-17
  • 1970-01-01
  • 2019-06-17
  • 2021-11-22
  • 2020-04-22
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多