android - 应该如何为具有多个字段的 Activity 实现 ViewModel

标签 android mvvm architecture android-architecture-components android-livedata

问题

有一个设置屏幕 (SettingsActivity),其中包含大约 10 个文本字段和 3 个按钮。在 onClick 上打开对话框以插入/编辑文本的文本字段将其内容保存在 SharedPreferences 中。这些按钮执行异步请求以检索内容并保存在其他地方。在请求期间,会显示一个对话框以通知进度。

初步解决方案

数据存储库

基本上是 SharedPreferences 的包装器,它有 10 个 getter 和 10 个 setter,每个字段一个。在 get[field_name] 上,DataRepositorySharedPreferences 获取值,在 set[field_name] 上,它提交给 SharedPreferences

View 模型

一个 ViewModel,它有 10 个 MutableLiveData 对象,每个字段一个。此类实现 LifecycleObserver 以了解 SettingsActivity 生命周期,因此它可以在 onCreate 上从存储库加载字段并将字段保存到存储库在 onDestroy 上。

还有 3 种方法可以执行由提到的 3 个按钮触发的 3 个异步请求。每个方法接收一个 OnRequestProgressListener 实例,该实例被传递给发出异步请求的类,用于通知 View 有关进度。

查看

一个有 10 个字段的 Activity ,从 ViewModel 观察 10 个 MutableLiveData。在每个字段的 onClick 上,将打开一个对话框以编辑/插入文本。在对话框的onPositiveButton上,调用对应字段的观察者。

该 Activity 实现了 OnRequestProgressListener 以根据异步请求进度显示和隐藏对话框。

初始解题

上面描述的设计似乎不正确。我可以指出一些:

  • ViewModel 中的 10 个 MutableLiveData
  • DataRepository 中有 10 个 getter 和 10 个 setter;
  • SharedPreferences 的存储库。
  • ViewModel 接收监听器以传递给执行异步请求的类,这些异步请求使用这些监听器通知 View 。中间有 ViewModel

正确的解决方案

这是正确的解决方案吗?如果不是,我相信不是,应该如何设计正确的解决方案?

最佳答案

  • 10 MutableLiveData in the ViewModel;

这完全没问题,如果您有 10 个独立的数据,您可以为每个数据创建一个 LiveData。

  • A repository for SharedPreferences.

存储库应该是对数据层的抽象,使您可以轻松切换实现。因此,在理论上拥有共享首选项的存储库是可以的。

但在你的情况下,如果存储库唯一做的是将调用转发到 SharedPreferences 因为将存储解决方案从共享首选项切换到其他东西的可能性非常低,我会摆脱存储库并直接使用 SharedPreferences 以简化代码。

  • 10 getters and 10 setters in the DataRepository;

同样,如果您在类中存储了 10 条数据并希望从外部访问它,您应该使用属性模式,这会导致 Java 中的 getter 和 setter。尽管在 Kotlin 中,您不需要显式编写 getter 和 setter。 此外,如果您决定删除 DataRepository,您将不需要该代码。

  • The ViewModel receives listeners to pass to the classes that do the async requests which use these listeners to notify the view. All with the ViewModel in the middle.

这听起来有点不对,如果你在你的 Activity 中创建一个监听器,你很可能会不小心使用引用 Activity 的匿名类,将它传递给 ViewModel 并得到内存泄漏。 您不应将 Activity 引用传递给 ViewModel。 正确的通信方式是通过 LiveData。您需要创建一个将发布进度的 LiveData,在 ViewModel 中使用它,为其提供进度,并且您的 Activity 需要订阅它以获取进度信息。 使用这种方法,您可以避免内存泄漏。

关于android - 应该如何为具有多个字段的 Activity 实现 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51307249/

相关文章:

android - 如何在 Flutter 中创建像 Telegram 或 WhatsApp 聊天页面这样的富文本输入?

C# UWP DataTemplate 内存泄漏

c# - 在通用 Windows 应用程序中使用 MVVM Light 进行验证

asp.net-mvc - ViewModel 和渲染

c++ - cuda内存带宽计算

nhibernate - 继承上的组合 - 额外的属性去哪里了?

architecture - 您在项目中遵循 n 层架构和关注点分离的严格程度如何?

android - TabActivity 中的多个 map v2

android - 在 Android 应用程序中实现类似 Google map 的搜索栏

android ViewPager xml膨胀错误