【问题标题】:AndroidViewModel vs ViewModelAndroidViewModel 与 ViewModel
【发布时间】:2017-10-24 05:48:54
【问题描述】:

随着 Android 架构组件库的引入,引入了几个新类,包括 AndroidViewModelViewModel。但是,我无法弄清楚这两个类之间的区别。 documentation 简洁地描述了AndroidViewModel 如下:

应用程序上下文感知ViewModel

我很欣赏它的简洁性,但这究竟意味着什么?我们什么时候应该选择使用AndroidViewModel 而不是ViewModel,反之亦然?

【问题讨论】:

    标签: android mvvm viewmodel android-architecture-components android-viewmodel


    【解决方案1】:

    AndroidViewModel 提供应用上下文

    如果您需要在 Viewmodel 中使用上下文,您应该使用 AndroidViewModel (AVM),因为它包含应用程序上下文。要检索上下文调用getApplication(),否则使用常规 ViewModel (VM)。

    AndroidViewModel 具有应用程序上下文。 我们都知道拥有静态上下文实例是邪恶的,因为它会导致内存泄漏!但是,拥有静态应用程序实例并不像您想象的那么糟糕,因为只有一个正在运行的应用程序中的应用程序实例。

    因此,在特定类中使用和拥有 Application 实例通常不是问题。但是,如果一个Application实例引用了它们,那就是因为引用周期的问题了。

    See Also about Application Instance

    AndroidViewModel 单元测试有问题

    AVM 提供了对单元测试有问题的应用程序上下文。单元测试不应处理任何 Android 生命周期,例如上下文。

    【讨论】:

    • 那为什么不总是使用AndroidViewModel呢?即使您现在不需要上下文,您以后也可能需要上下文。这样做有什么坏处吗?
    • @T.Rex 如果您查看代码,它扩展了ViewModel,只有一个指向应用程序的字段。如果我不需要它,我不喜欢使用带有Application 参数的强制构造函数(AndroidViewModel 需要),而只使用ViewModel。当我将来需要上下文时,我可以轻松更改它。
    • 当您想将ViewModel 与Fragment 一起使用或在同一Activity 的不同Fragment 之间共享ViewModel 时使用。
    • @T.Rex 不会使用AndroidViewModel - 依赖于Context - 使得无法在常规单元测试中对其进行测试,只留下仪器测试作为可能?我自己(还)没有玩弄它,这只是一个想法
    • AndroidViewModel 和 ViewModel 是一样的,唯一的区别是 AndroidViewModel 包含了应用上下文。您可以使用 ViewModel 并将上下文传递给 ViewModel 以实现从 MediaStore 加载数据的功能,或者将 AndroidViewModel 与应用程序上下文一起使用。
    【解决方案2】:

    终于得到了一个更简单的解释,有点…… ...AndroidViewModel 类是 ViewModel 的子类,与它们类似,它们旨在存储和管理 UI 相关数据,负责为 UI 准备和提供数据,并自动允许数据在配置更改后继续存在。

    与 AndroidViewModel 的唯一区别是它带有应用程序上下文,如果您需要上下文来获取系统服务或有类似要求,这将很有帮助。粗体文本使其更易于感知.

    【讨论】:

    【解决方案3】:

    AndroidViewModelViewModel 的子类。它们之间的区别在于我们可以传递应用程序上下文,它可以在需要应用程序上下文时使用,例如在存储库中实例化数据库。

    AndroidViewModel 是一个应用程序上下文感知的 ViewModel。

    AndroidViewModel:

    public class PriceViewModel extends AndroidViewModel {
    private PriceRepository priceRepository;
    
    public PriceViewModel(@NonNull Application application) {
        super(application);
        priceRepository= new PriceRepository(application);
        allPrices = priceRepository.getAllPrices();
    }
    

    视图模型:

    public class PriceViewModel extends ViewModel {
    public PriceViewModel() {
        super();
    }
    

    只有在需要应用程序时才应该使用 AndroidViewModel 上下文。

    您不应该在 ViewModel 中存储活动的引用或引用活动的视图。因为 ViewModel 旨在延长活动的寿命,并且会导致内存泄漏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-15
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-07
      相关资源
      最近更新 更多