代码之家  ›  专栏  ›  技术社区  ›  Damn Vegetables

viewModelScope.在viewModel变量onDestory()不起作用的情况下启动

  •  0
  • Damn Vegetables  · 技术社区  · 2 年前

    下面的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");
        }
      }
    
    0 回复  |  直到 2 年前
        1
  •  2
  •   Klitos G.    2 年前

    我在下面的回答是基于这样一个假设,即您的“活动”正在完成,并且没有被重新创建(例如,在配置更改中会发生这种情况)

    viewModelScope是遵循ViewModel生命周期的一个特殊作用域。这意味着,如果调用了viewModel.onCleared(),则会取消viewModelScope。附带说明:如果您试图在取消的范围内启动协同程序,则不会发生任何事情。

    现在看看 ViewModel Lifecycle 如果你的活动正在完成,那么在你的活动的onDestroy之后不久就会调用onCleared()。

    说到你的代码,我认为你试图开始的工作永远不会开始,因为你的onCleared是在Dispatchers之前调用的。IO成功启动作业

    第二个代码块(我在这里猜测)可能正在创建ViewModel的另一个实例,该实例在某种程度上能够在活动销毁后存活下来,因为它没有接收到活动生命周期调用(onDestroy之后没有发生其他事情)。 这可能是一个bug。在我看来,你不应该被允许在onDestroy内部向提供商请求视图模型