安卓 ViewModel 设计/架构

3
我是一名Android初学者,希望能够得到关于应用程序架构的建议 - 特别是与使用ViewModel相关的内容。每个屏幕都会发出新的网络请求,因此没有本地数据库。稍后我会考虑实现Room或类似的东西。
主活动(电影列表):
我有一个活动,其中包含一个100%大小的可循环视图,显示电影列表。每部电影在recyclerview中都有一个封面图像,用户可以点击该图像以导航到播放器视图。 MainActivity(及其recycler view)由ViewModel支持。 Movie对象(由LiveData包装)具有您期望的内容,例如标题,类别,封面图像和指向mp4文件的URL。
private val movies = MutableLiveData<List<Movie>>()

为了转换到PlayerActivity,意图将所选电影的ID作为字符串额外参数传递。

PlayerActivity

当在MainActivity的recycler视图中选择电影单元格时,我创建一个新的意图来转换到PlayerActivity,即播放电影的地方。这里还显示有电影封面图像的imageView。此视图也由ViewModel支持。

private val selectedMovie = MutableLiveData<Movie>()

在OnCreate()方法中,我从意图中获取movie_id字符串附加项,并创建ViewModel(ViewModel使用movie_id进行网络请求)。此视图还有一个按钮,当触摸时,转换用户到ScreenshotActivity。跳转到ScreenshotActivity的意图也传递了movie_id作为字符串附加项。

ScreenshotActivity

该活动显示电影截图的recyclerview,并且当触摸时,会向服务器发送网络请求,以使用其中一张截图更新电影的封面图像。该活动从PlayerActivity意图中获取movie_id额外信息来设置视图。

问题

  1. 显然每次做网络请求都很浪费资源,我理解应该使用类似room的本地缓存此信息。 如果没有本地数据库,有没有更好的方法来处理上述ViewModel?也许是单个可由上述3个活动访问的ViewModel?这样,可以直接对电影对象进行更改并在所有视图之间同步?有没有关于如何实现这一点的好例子?
  2. 鉴于我当前的3个活动各自具有ViewModel,当在ScreenshotActivity中更新截图时,如何通知MainActivity更新截图并通知PlayerActivity更新播放器上的封面图像?

1
Activity必须提供自己的ViewModel,因为ViewModel的生命周期与1个Activity紧密相关。此外,如果您在后台完成图像下载,请将该图像设置在LiveData中,它将触发View部分(即Activity)的更新,但对于3个Activities的情况,请尝试创建一个Singleton Repository,这个Repository在ViewModel实例之间共享。 - Enzokie
1个回答

1
“每次进行网络请求显然是非常浪费的,我理解我应该使用像 room 这样的东西来将这些信息缓存到本地。”
“好吧,这取决于你的网络请求的大小。它们是几兆字节吗?那么是的,我会将一些电影图片缓存到本地。”
“在没有本地数据库的情况下,有更好的方法可以像上面的 ViewModel 一样完成我的工作吗?或许可以使用一个单独的 ViewModel,所有 3 个活动都可以访问它?”
“嗯,我认为你目前的方法并不差,我们应该看看 API。在你的 MovieList 中,你获取了所有电影的数据对吧?我认为在那个时候,你应该尽量减小 API 发送的数据。然后当仅选择一个电影时,下载内容(如屏幕截图)并将其缓存在本地。如果你无法编辑 API,那么是的,我建议你下载所需的所有内容,并尽可能多地重用它们。”

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

此外,请注意,我不建议您为多个活动使用同一个ViewModel。每个Activity都依赖于自己的ViewModel

这样做可以直接对电影对象进行更改并在所有视图之间同步吗?有没有关于如何做到这一点的好例子?

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

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

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

然后,您可以随时调用以下方式通知已订阅的活动

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接