【问题标题】:Does a coroutine prevent an object from being garbage collected?协程是否会阻止对象被垃圾收集?
【发布时间】:2020-07-12 10:19:25
【问题描述】:

我看过一些教程,其中写入 Room 是在使用 viewModelScope 启动的协程中执行的,所以当 ViewModel 被销毁时它会被取消。但我希望无论如何都要写入数据。所以我想在一个不依赖于Activity生命周期的范围内启动这个协程。

class MyApplication : Application() {
  val applicationScope = CoroutineScope(SupervisorJob())
}

如果我使用这个范围在 ViewModel 中启动一个长时间运行的协程,即使 Activity 被销毁,在协程完成之前,ViewModel 也不会被垃圾回收,这是真的吗?

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    没错。从任何地方启动一个长时间运行的协程将保留它引用的对象,直到它完成或取消。

    这就是为什么在活动和片段中的ViewModellifecycleScope 中使用viewModelScope 是可取的。因为他们知道如何取消这些工作。

    https://developer.android.com/topic/libraries/architecture/coroutines

    但是,如果您不引用您的活动或上下文(实际上是活动本身),它们就不会泄漏。

    
       CoroutineScope(SupervisorJob())
                .launch { 
                    // activity.getString(R.string.something) // Memory leak!
                    applicationContext.getString(R.string.something) // Memory leak on applicationContext but not on activity. That's fine.
    
                }
    . . .
       }
    

    或者至少我期望它是这样工作的。但是当你在那里做withContext(NonCancellable) 时似乎有一个意想不到的行为。见https://github.com/Kotlin/kotlinx.coroutines/issues/1061

    简而言之,这样写就不会引用Activity 和其他引用Activity 的对象,这是一种很好的做法。否则预计事情会泄漏。如果您在协程中引用任何 viewmodel 对象,我也会这么说。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      • 2012-12-20
      • 2015-05-04
      • 2014-03-18
      • 1970-01-01
      相关资源
      最近更新 更多