簡體   English   中英

使用協程時使用 GlobalScope.launch 的效果

[英]Effect of using GlobalScope.launch while using coroutine

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的情況下哪個更好用嗎

我見過:

為什么不使用 GlobalScope.launch?

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

有人可以解釋在我的 1 和 2 的情況下哪個更好用嗎

兩者都不。

他們兩個的問題是他們幾乎不受約束。 他們不尊重應用程序的生命周期,這意味着如果您的應用程序關閉(或用戶離開該屏幕)而某些協程在這些范圍內運行,它們將不會停止執行並且會泄漏協程(應用程序甚至可能崩潰)

我的應用程序何時會崩潰:

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

在這里,如果用戶在fetchUserData暫停時離開屏幕。 然后該代碼不會停止執行,當fetchUserData返回時,它將嘗試更新 UI,但由於屏幕已更改,它將引發異常並且您的應用程序將崩潰。

我們想要的是協程在不再需要時應該停止。 如果您使用GlobalScope ,您將失去所有控制權。 對於自定義CoroutineScope ,如果您在正確的時間取消它,一切都很好,否則它也是有害的。

有什么選擇?
您可以/應該使用viewModelScope提供的內置范圍,如lifecycleScope范圍和視圖模型范圍。 第一個遵循活動(或片段)的生命周期,而第二個在視圖 model 被破壞時被清理。

所以,這是一般的建議。 針對您的具體情況,

  • 在您的第一種情況下,您甚至不需要協程 scope 因為notify是一個非常簡單的 function (既不暫停也不阻塞)
  • 在第二種情況下,您有一個無限循環,當滿足特定條件時會中斷。 由於您在 ViewModel 中有此代碼,因此您很可能不希望它在視圖 model 被清除后運行。 如果您使用CoroutineScope()GlobalScope ,您將無法控制它。 因此,您應該在此處使用viewModelScope ,以便在不再需要工作時停止無限循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM