android - Android JetPack 的共享 ViewModel 生命周期

标签 android android-fragments android-architecture-components android-jetpack model-view

文档 https://developer.android.com/topic/libraries/architecture/viewmodel#sharing描述了我们如何在不同的 Fragment 之间共享同一个 ViewModel。

我的单个 Activity 应用程序中有一些复杂的页面,其中包含容器和选项卡 fragment 。每个这样的页面都有自己的 ViewModel,它应该与所有包含的 fragment 共享。

这里的关键技巧是使用 Activity 而不是 Fragment 来保存我的 ViewModel。

问题是我的 Activity 可以有多个页面和自己的模型,并且一直保持特定页面的 View 模型是设备资源的浪费。

有什么方法可以控制 ViewModel 的生命周期,以便在用户离开页面时销毁它?

我想用容器 fragment 代替 Activity :

model = ViewModelProviders.of(getPageContainerFragment()).get(SharedViewModel.class);

但发现这个想法不太好,因为所有子 fragment 都应该知道父 fragment ,这可能不太好。

有没有其他方法可以妥善处理这种情况?

最佳答案

如果我没弄错的话,你的问题是“如何释放资源”而不是“如何清除 View 模型”。
所以,你可以让你的 View 模型尽可能轻,像这样:

abstract class MyViewModel: ViewModel() {
    abstract fun freeResources()
}

并在页面更改时在 OnPageChangeListenerOnTabSelectedListener 或您使用的任何监听器中调用 vm.freeResources()
在这种情况下,您应该使用 Activity 范围获取 viewModel。

或者,如果您真的希望您的 View 模型为 onCleared() 然后创建新 View 模型,我建议您使用 scoped-vm图书馆。它允许您为由字符串名称标识的范围请求 View 模型。

ScopedViewModelProviders
     .forScope(fragment, "scope")
     .of(activity)
     .get(MyViewModel::class.java)

一旦从该范围请求某些东西的最后一个 fragment 被销毁,范围就会被清除(其中的 View 模型也是如此)。因此,请为您的页面使用不同的范围。
但是,在这种情况下,您应该仔细检查 fragment 的生命周期:如果您的 PagerAdapter 持有它们以供重复使用,则范围将永远不会被清除,只有手动方法才能帮助您。

关于android - Android JetPack 的共享 ViewModel 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53236574/

相关文章:

android - 奇怪的 fragment 生命周期错误

android - 带有 UI 和内存泄漏的保留 fragment

android - 房间 : Renaming Table doesn't update Foreign Key Table Reference

Android Studio 调色板被禁用

java - 无法实例化 fragment 确保类名存在

Android Studio 3.1 在没有 --min-sdk-version >= 24 的情况下使用默认或静态接口(interface)方法

安卓机房 : LiveData callback of update insert?

android - 仅具有上下文的导航架构组件导航

android - 使用 RoboSpice 将多个 Web 服务聚合到一个响应中

android - Sugar ORM 无法在 Kotlin 中保存