簡體   English   中英

使用 MainScope() 和 requireActivity().lifecycleScope 在片段內啟動協程有什么區別?

[英]What's the difference between launching a coroutine inside a fragment using `MainScope()` and `requireActivity().lifecycleScope`?

這對啟動需要在片段生命周期之后繼續的操作(如數據庫寫入)有意義嗎?

代碼示例:

requireActivity().lifecycleScope.launch {
         // suspend function invocation
}

MainScope().launch { 
        // suspend function invocation
}

MainScopelifecycleScope最重要的區別在於啟動協程的取消管理。

我知道你的問題是關於 requireActivity().lifecycleScope,但讓我一步一步來。

使用生命周期范圍,取消是自動為您完成的 - 在 Fragment 或 Activity 的 onDestroy() 事件中,這取決於您掛鈎的生命周期。

使用 mainScope,您只能靠自己,並且必須自己添加 scope.cancel(),如下所示:

class MyActivity: Activity {
    private val scope = MainScope()
    // launch a coroutine on this scope in onViewCreated
    override fun onDestroy() {
        super.onDestroy()
        //you have to add this manually
        scope.cancel()
    }
}

更多信息請參見:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-main-scope.ZFC35FZ30D52C7A5E396

換句話說,您使用主 scope手動執行(或應該執行)的操作,生命周期范圍會自動為您執行。

現在,在這一點上,你可以(也許)說,啊哈 - 這是我想要的主要 Scope,因為我的操作不會自動取消,這正是我想要的,所以我可以跳過添加取消調用。

在某種程度上,是的,你會得到你想要的,因為它確實會繼續運行一段不確定的時間,直到 Fragment 及其變量被垃圾收集,但你將無法再訪問那個 scope - 片段消失了,當您再次導航到片段時,將創建一個新實例,以及一個新的主 scope。 當然,您無法保證在垃圾收集開始之前需要多長時間。那么異常呢?

現在到requireActivity().lifecycleScope。

如果你使用 requireActivity().lifeCycleScope,你顯然會跳上 Activity 生命周期並獲得兩個優勢 - 更長的生命周期(大概是 Activity 中還有其他片段,並且說從有問題的片段返回只是導航到另一個片段在同一個活動中,並且不退出應用程序),並在 OnDestroy() 中自動取消。

這可能就足夠了。 但是a)如果您需要,您的工作句柄仍將保留在片段中,並且再次,一旦您丟失片段,您將無法再訪問該工作(假設您需要它),並且b)您的活動將無法在配置更改中幸存(除非您明確禁止它們)。 如果要允許和處理配置更改,go 與活動上的 viewModelScope(並在活動和片段之間使用共享視圖 model)。

ViewModel class 允許數據在屏幕旋轉等配置更改中保留下來。

最后,如果這些都不夠(您的“Db 保存”操作需要很長時間),請使用服務(或 WorkManager 等)。 但到那時,要問的正確問題將是“為什么要花這么長時間?” 並專注於此。

暫無
暫無

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

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