【问题标题】:Is it okay to pass views into AndroidViewModel可以将视图传递给 AndroidViewModel
【发布时间】:2020-11-08 05:12:57
【问题描述】:

我知道将视图传递给 ViewModel 类会导致内存泄漏,但如果我将视图(例如 ProgressBar)传递给 AndroidViewModel 类,如下所示,它也会导致内存泄漏吗?

class MainActivityViewModel (application: Application, progressBar: ProgressBar): AndroidViewModel(application) {
    var name: LiveData<String> = Transformations.map(docRef) {
        progressBar.visibility = View.GONE
        it.getString("string")
    }
}

我将使用数据绑定从我的布局文件中调用name,例如android:text="@{viewModel.name]"

上面的代码会不会造成内存泄漏?

【问题讨论】:

  • 不要将任何与上下文相关的内容传递给 viewmodel ,包括任何类型的视图。
  • 将引用直接传递给视图模型是一个坏主意,原因有几个。 1) 如果在视图模型中保留硬引用,则潜在的内存泄漏 2) 关注的分离 - 如果视图模型被传递给视图,那么它可以访问整个 View 对象 - 它应该被解耦 3) mvvm 设计模式,视图模型应该只对用户事件做出反应,即 onLoad(),`onSignIn(args ...)` 或提供 UI 数据。当然这是你的选择——但这是我对你的问题的直接挑战。

标签: android kotlin data-binding android-databinding


【解决方案1】:

上面的代码会不会造成内存泄漏?

是的,如果设备发生配置更改,例如用户旋转屏幕。

在这种情况下,您的活动及其视图将被销毁并重新创建,但您的MainActivityViewModel 将被保留并提供给新的活动实例。但是,它仍然会引用旧活动中的progressBar。这意味着:

  • Android 无法对旧 Activity 进行垃圾收集,因为您的视图模型持有来自该 Activity 的对 View 的引用

  • progressBar 的调用最多不会有任何效果,最坏的情况会崩溃(例如,NullPointerException),因为该视图没有被活动活动使用

相反,让您观察name 的代码处理更改此progressBar 的可见性。

【讨论】:

    【解决方案2】:

    当然。 如果你使用数据绑定, 你可以用一个字段来标记视图已经消失, 就像你使用“名字”的方式一样

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多