【问题标题】:run coroutine with parent's ViewModel scope使用父级的 ViewModel 范围运行协程
【发布时间】:2021-03-16 10:48:11
【问题描述】:

我刚开始使用协程,我不太确定我是否以正确的方式使用它。 我的 android 应用程序只有 1 个带有多个片段和对话框片段的活动。我创建了一个功能,询问用户他/她是否接受做某事。该应用程序显示带有是/否按钮的DialogFragment。如果用户点击Yes,它将关闭对话框并执行此工作。

我想在活动的 viewModelScope 中开始繁重的工作,因此当用户导航到其他片段时,它将继续在后台事件中执行。

父视图模型:

class ActivityViewModel: ViewModel(){
    fun doJob(){
        viewModelScope.launch{
            //Do the heavy job
        }
    }
}

对话框片段视图模型:

class DialogViewModel: ViewModel(){
    var activityVM: ActivityViewModel
    fun onYesClicked(){
        activityVM.doJob()
    }
}

我猜该作业是在 DialogFragment 的 ViewModel 范围而不是 Activity 的 ViewModel 范围下执行的。这会导致一个问题,即当作业运行速度比预期慢时,它会因为对话框被关闭而被取消。

我不确定这是否是常见做法,因为我找不到任何类似的讨论。请帮助指出我在此代码上哪里错了,或者有适合这种情况的最佳实践。

【问题讨论】:

  • 如果您希望它仅在您的应用程序打开时执行,您可能应该在您的 Dialog 和您的 Activity 之间创建一个回调,这样您就可以使用 Activity 范围开始工作。但是对于繁重的负载,您可能需要查看 WorkManager 或 Foreground Services。
  • 感谢@rlino 的想法,我应用了 Android 架构组件,因此我可以在子视图/片段中轻松访问父视图模型。我不想使用回调卷土重来。切换到前台服务或 WorkManager 的工作不会太繁重。它所做的只是向连接的蓝牙设备发送一个命令,这需要 0.5-1 秒。

标签: android kotlin-coroutines


【解决方案1】:

我最终在活动视图模型上使用了自定义协程范围。通过这样做,我在活动关闭事件而不是对话框片段关闭时手动取消协程。

class ActivityViewModel: ViewModel(){
    private val mainActivityScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    fun doJob(){
        mainActivityScope.launch{
            //Do the heavy job
        }
    }

    override fun onCleared() {
        super.onCleared()
        mainActivityScope.cancel()
    }

}

class DialogViewModel: ViewModel(){
    var activityVM: ActivityViewModel
    fun onYesClicked(){
        activityVM.doJob()
    }
}

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 1970-01-01
    • 2022-01-18
    • 2013-01-31
    • 2020-10-22
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多