首页 文章

手动清除Android ViewModel?

提问于
浏览
2

参考 android.arch.lifecycle.ViewModel 类 .

ViewModel 的范围限定为与其相关的UI组件的生命周期,因此在基于 Fragment 的应用程序中,这将是片段生命周期 . 这是件好事 .


在某些情况下,人们希望在多个片段之间共享 ViewModel 实例 . 具体来说,我对许多屏幕与相同基础数据相关的情况感兴趣 .

(当多个相关片段显示在同一屏幕上但this can be worked around by using a single host fragment as per answer below时,文档建议采用类似的方法 . )

这在_342491中讨论:

ViewModels还可以用作活动的不同片段之间的通信层 . 每个Fragment都可以通过其Activity使用相同的密钥获取ViewModel . 这允许以解耦方式在片段之间进行通信,使得它们永远不需要直接与其他片段对话 .

换句话说,要在表示不同屏幕的片段之间共享信息, ViewModel 应限定为 Activity 生命周期(根据Android文档,这也可以在其他共享实例中使用) .


现在在新的Jetpack导航模式中,建议使用“One Activity / Many Fragments”架构 . 这意味着活动在应用程序使用的整个过程中都存在 .

即任何作用于 Activity 生命周期的共享 ViewModel 实例永远不会被清除 - 内存将继续使用 .

为了保留内存并在任何时间点使用所需的内存,最好能够在不再需要时清除共享的 ViewModel 实例 .


如何从它的 ViewModelStore 或持有者片段中手动清除 ViewModel

3 回答

  • 1

    如果您检查代码here,您将发现,您可以从 ViewModelStoreOwnerFragmentFragmentActivity 获取 ViewModelStore ,例如,实现该接口 .

    从那里你可以调用 viewModelStore.clear() ,正如文档所说:

    /**
     *  Clears internal storage and notifies ViewModels that they are no longer used.
     */
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
    
  • 0

    通常,您不会手动清除ViewModel,因为它是自动处理的 . 如果您觉得需要手动清除ViewModel,那么您可能在ViewModel中做了太多...

    使用多个视图模型没有任何问题 . 第一个可以作为活动的范围,而另一个可以作用于片段 .

    尝试仅将Activity作用域的Viewmodel用于需要共享的内容 . 并在Fragment Scoped Viewmodel中放置尽可能多的东西 . 片段被销毁时,将清除Fragment范围的视图模型 . 减少总体内存占用 .

  • 0

    如果您不希望 ViewModel 的范围限定为 Activity 生命周期,则可以将其范围限定为父片段的生命周期 . 因此,如果要在屏幕中与多个片段共享 ViewModel 的实例,则可以布置片段,使它们共享一个共同的父片段 . 这样,当您实例化 ViewModel 时,您可以这样做:

    CommonViewModel viewModel = ViewModelProviders.of(getParentFragment()).class(CommonViewModel.class);
    

    希望这有帮助!

相关问题