简体   繁体   English

使用父母的 ViewModel scope 运行协程

[英]run coroutine with parent's ViewModel scope

I just getting started with coroutines and I'm not quite sure whether I'm on the right way using it.我刚开始使用协程,我不太确定我是否以正确的方式使用它。 My android app has only 1 activity with several fragments and dialog fragments.我的 android 应用程序只有 1 个带有多个片段和对话框片段的活动。 I created a feature which asked user if he/she accepts to do something.我创建了一个功能,询问用户他/她是否接受做某事。 The app shows a DialogFragment with Yes/No buttons.该应用程序显示一个带有是/否按钮的DialogFragment If user clicks Yes , it closes the dialog and does the job.如果用户单击Yes ,它将关闭对话框并执行该工作。

I would like to start the heavy job in activity's viewModelScope, so it will continue to execute at background event when user navigates to other fragments.我想在活动的 viewModelScope 中开始繁重的工作,因此当用户导航到其他片段时,它将继续在后台事件中执行。

Parent's ViewModel:父母的 ViewModel:

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

Dialog Fragment ViewModel:对话框片段视图模型:

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

I guess the job is executed under DialogFragment's ViewModel scope instead of Activity's ViewModel scope.我猜这项工作是在 DialogFragment 的 ViewModel scope 而不是 Activity 的 ViewModel scope 下执行的。 It leads to an issue that when the job runs slower than expected, it's canceled because the dialog is dismissed.这会导致一个问题,即当作业运行速度比预期慢时,它会因为对话框被关闭而被取消。

I'm not sure if this is common practice as I can't find any similar discussion.我不确定这是否是常见做法,因为我找不到任何类似的讨论。 Please help to point me where am I wrong on this code or there is a best practice for this case.请帮助指出我在此代码上哪里错了,或者有适合这种情况的最佳实践。

I ended up with a custom coroutine scope on the activity viewModel.我最终在活动视图模型上使用了自定义协程 scope。 By doing this, I manually cancel the coroutines when activity closing event instead of dialog fragment dismissing.通过这样做,我在活动关闭事件而不是对话框片段关闭时手动取消协程。

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()
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用 Hilt 获取 ViewModel 的协程 scope - Get ViewModel's coroutine scope with Hilt 用于在 ViewModel 外部实例化的 RoomDatabase 中的 RoomDatabase.Callback() 的协程 scope? - Coroutine scope for a RoomDatabase.Callback() in a RoomDatabase instantiated outside the ViewModel? 旋转片段时使用哪个协程 scope? 我们可以从视图模型中启动协程吗? - Which coroutine scope to use when rotating fragments? Can we launch a coroutine from a viewmodel? Android ViewModel协程模式 - Android viewmodel coroutine pattern 在 onPause() 期间使用协程保存数据(避免 ViewModel 取消和全局协程范围) - Saving data with coroutines during onPause() (avoiding ViewModel cancellation and global coroutine scope) 使用导航组件在父片段的 scope 中共享 ViewModel - Shared ViewModel in scope of parent fragment using Navigation Component 协程的父子关系,获取特定的孩子并取消? - Coroutine's parent child relationship, getting a particular child and cancelling it? BindingAdapter 与协程 scope - BindingAdapter with coroutine scope Kotlin Coroutine ViewModel UnitTesting 不涵盖 viewmodel - Kotlin Coroutine ViewModel UnitTesting does not cover viewmodel 如何在 Kotlin 中使用 ViewModel 测试协程? - How to test Coroutine with ViewModel in Kotlin?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM