![](/img/trans.png)
[英]Launching a coroutine from a Fragment using viewLifecycleOwner's 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
}
MainScope和lifecycleScope最重要的區別在於啟動協程的取消管理。
我知道你的問題是關於 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()
}
}
換句話說,您使用主 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.