Android ViewModel设计/架构

时间:2018-07-19 07:30:19

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

我是一名Android初学者,只是在寻找有关应用程序体系结构的一些建议-特别是与使用ViewModels有关。没有本地数据库,每个屏幕都会发出一个新的网络请求。稍后我会考虑实现空间或类似功能。

主要活动(电影列表)

我有一个活动,其中100%大小的回收视图显示了电影列表,recyclerview中的每个电影都有一个封面图像,用户可以触摸该封面图像以导航到播放器视图。 MainActivity(及其回收视图)由ViewModel支持。 Movie对象(由LiveData包装)具有您期望的内容,例如标题,类别,封面图像,mp4文件的URL。

private val movies = MutableLiveData<List<Movie>>()

要过渡到PlayerActivity,目的是将所选电影的ID作为额外的字符串传递。

PlayerActivity

在MainActivity的“回收者”视图中选择一个影片单元时,我创建了一个新的意图,以过渡到播放该影片的PlayerActivity。还有一个imageView,其中也显示了电影封面图像。此视图还由ViewModel支持。

private val selectedMovie = MutableLiveData<Movie>()

在OnCreate()中,我从意图中额外获得了movie_id字符串,并创建了ViewModel(然后ViewModel使用movie_id进行网络请求)。该视图还具有一个按钮,当触摸该按钮时,会将用户转换为ScreenshotActivity。过渡到ScreenshotActivity的目的也将movie_id作为额外的字符串传递。

ScreenshotActivity

具有所显示电影的屏幕快照的回收视图,并且在被触摸时,网络请求将被发送回服务器,以使用这些屏幕快照之一来更新电影的封面图像。此活动从PlayerActivity意图中获取movie_id的额外内容来设置视图。

问题

  1. 每次都进行网络请求显然很浪费,我知道我应该使用例如room之类的东西在本地缓存此信息。 在缺少本地数据库的情况下,是否有更好的方法可以使用ViewModels完成上述操作?也许上述三个活动都可以访问一个视图模型?这样,可以直接对电影对象进行更改并在所有视图之间同步吗?有关如何执行此操作的任何好的示例?
  2. 考虑到我当前用于3x活动的3x ViewModel,当在ScreenshotActivity中更新屏幕截图时,如何通知MainActivity更新屏幕截图,以及通知PlayerActivity更新封面图像(在播放器上)?

1 个答案:

答案 0 :(得分:1)

  

每次都进行网络请求显然很浪费,我知道我应该使用例如room之类的东西在本地缓存此信息。

嗯,这仅取决于您的网络请求的大小。他们是几兆字节吗?然后,是的,我将在本地缓存电影的某些图像。

  

在没有本地数据库的情况下,有没有更好的方法来执行操作   我在上面用ViewModels做吗?也许一个视图模型可以   可以被以上所有3个活动访问?

嗯,我认为您当前的方法一点也不差,我认为我们应该看看API。在您的MovieList中,您可以获得电影的所有数据吗?我认为那时候您应该缩小API发送的数据。然后,仅选择一部电影时,下载诸如屏幕截图之类的内容,并将其本地缓存。如果您不能编辑API,那么可以,我建议您下载所需的所有内容并尽可能地重复使用。

由于您的数据已经在private val movies = MutableLiveData<List<Movie>>()中,为什么不将所选的Movie传递给PlayerActivity

还请注意,我不建议您在多个活动中使用相同的ViewModel。每个Activity都取决于自己。

  

这样做,可以直接对电影对象进行更改,   在所有视图中同步了吗?有关如何执行此操作的任何好的示例?

应用Telegram有一些不错的ObserverPattern,我在应用中经常使用它。参见此类:NotificationCenter.java。这允许Activity订阅事件。如果另一种方法调用event,则会触发所有订户。这可以帮助您“通知”活动以进行某些工作。您可以浏览存储库以了解如何使用它。

基本上,当您想在events中收听Activity时,需要实现NotificationCenter.NotificationCenterDelegate。然后覆盖didReceivedNotification(int id, Object... args),然后(un)像这样订阅events

NotificationCenter.getInstance().addObserver(this, NotificationCenter.scheduleReload);

然后,您可以通过以下任何方式通知已订阅的Activities

NotificationCenter.getInstance().postNotificationName(NotificationCenter.scheduleReload);