【问题标题】:viewModelScope.launch with the viewModel variable onDestory() not workingviewModelScope.launch 与 viewModel 变量 onDestory() 不工作
【发布时间】:2023-03-13 15:55:01
【问题描述】:

下面的 coe 只打印“onDestory”,而不是“launch”。但是,如果我像第二个块一样修改代码,则会打印“启动”。这是为什么?类成员变量在onDestroy()之前被销毁了吗?

  lateinit var viewModel: ArticleViewModel;

  override fun onCreate(savedInstanceState: Bundle?)
  {
    super.onCreate(savedInstanceState)
    viewModel = ViewModelProvider(this)[ArticleViewModel::class.java];
  ....

  override fun onDestroy()
  {
    super.onDestroy()
    Log.d("stack", "onDestroy");

    viewModel.viewModelScope.launch(Dispatchers.IO)
    {
      Log.d("stack", "launch");
    }
  }

修改

  override fun onDestroy()
  {
    super.onDestroy()
    Log.d("stack", "onDestroy");
    val vm = ViewModelProvider(this)[ArticleViewModel::class.java];
    vm.viewModelScope.launch(Dispatchers.IO)
    {
      Log.d("stack", "launch");
    }
  }

【问题讨论】:

  • viewmodel 范围将在 onDestroy 之后调用 onCleared,所以我认为这种方法不起作用。如果您需要在后台创建一些工作,也许您可​​以创建一个工作管理器来完成任务。 Viewmodel 范围 -> developer.android.com/topic/libraries/architecture/…
  • @ManuelMato 我试图将活动的状态保存到 Room 数据库中,当在主线程中调用时会引发异常。我将代码更改为CoroutineScope(Dispatchers.IO),当活动是第二个活动时,它似乎可以工作。但是当它是主要活动时,按下后退按钮时似乎没有调用onDestory,因此没有调用我的状态保存代码。
  • 因为当你按下返回按钮时,activity没有被销毁,处于onStop生命周期中。如果您想在返回时销毁活动,则需要覆盖 onBackPressed 方法并调用 finish()
  • @ManuelMato 你所说的 onStop 状态,如果你按下 HOME 按钮,将是真的(在大多数情况下)。具有单个 Activity 的简单应用程序通常会在您按下 BACK 按钮后被销毁。所有这一切都以大多数情况免责声明表示。根据系统对资源的激进程度,不同的 Android 实现的行为会有所不同。无论如何,+1 如果您实施 onBackPressed 您可以更好地控制按回时正在运行的内容。保存到数据库可能发生在 onBackPressed 内部,等待它完成然后完成活动

标签: android kotlin kotlin-coroutines


【解决方案1】:

我在下面的回答是基于您的 Activity 正在完成而不是重新创建的假设(例如,在配置更改中会发生这种情况)

viewModelScope 是一个特殊的范围,它遵循 ViewModel 的生命周期。这意味着如果调用 viewModel.onCleared() 则 viewModelScope 将被取消。旁注:如果您尝试在取消的范围内启动协程,则不会发生任何事情。

现在看看ViewModel Lifecycle 如果您的 Activity 正在完成,那么 onCleared() 将在您的 Activity 的 onDestroy 之后立即被调用。

谈到你的代码,我认为你试图开始的工作永远不会开始,因为你的 onCleared 在 Dispatchers.IO 设法开始工作之前被调用

第二个代码块(我在这里做个猜测)可能正在创建 ViewModel 的另一个实例,它以某种方式设法超过了活动的销毁,因为它没有收到活动生命周期调用(在 onDestroy 之后没有发生任何其他事情)。 这可能是一个错误。在我看来,你不应该被允许在 onDestroy 中向提供者请求视图模型

【讨论】:

  • 是的,我按下了返回按钮来关闭活动。想想看,活动可能会在“launcg”中做这件事之前结束。为什么我没有意识到...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-21
  • 2019-01-12
  • 2022-01-08
  • 1970-01-01
  • 2020-02-24
  • 1970-01-01
相关资源
最近更新 更多