我们是否应该使用ViewModels在单个活动App Architecture中的2个不同片段或捆绑软件之间进行通信?

Ana*_*mar 11 android bundles android-lifecycle android-fragments android-viewmodel

场景1-如果我们ViewModels用来在片段之间进行通信,则ViewModel必须通过活动引用来创建,因此必须将其保留在内存中,直到活动被销毁为止。

方案2-在主从流程ViewModel中使我们的生活更轻松,但内存使用问题仍然存在。

场景3- viewModelScope在新版本的Arch库中,我们将取消具有Fragment / Activity生命周期的作业,但是如果ViewModel使用活动引用创建了作业,则它将停留在那里直到活动被销毁为止。因此,该作业仍可以执行并且片段已经消失。

Shi*_*ete 6

您可以使用ViewModels在两个不同的片段(也称为SharedViewmodels)之间进行通信,因为它很简单,但并不完美。

如您所知,SharedViewModels必须处于活动状态,直到第一个联合父级(活动或片段)处于活动状态。

可是等等 ...

ViewModels的目的是什么?

我们是否只为片段之间的通信创建ViewModels?绝对不。

使用ViewModels是否违背ViewModels的目的?不,我说将它们用于片段之间的通信不是完美的,但是如果您有一个小型项目,则可以使用它们,因为它很简单。

那么我该怎么办,而不是使用ViewModels在片段之间进行通信?您可以构建独立的UI组件,并将它们用于片段之间的通信。

构建这个怪异的独立UI组件有什么优势?这样,每个组件都有其自己的ViewModel(或Presenter),并且它们之间没有任何父/子关系。取而代之的是,它们从相同的业务逻辑进行更新,或者在响应式编程中,它们只是遵循相同的模型。

构建独立的UI组件是什么意思,以及如何构建它们?如果您已经熟悉反应式编程,那么我建议您阅读Hannes Dorfmann的这篇很棒的博客文章。如果您不这样做,我只是建议使用EventBus库在片段之间进行通信,但是您很快就会意识到该库的过多使用会导致产生意大利面条式代码。


son*_*net 5

场景

如果片段不是流/组的一部分,则不要共享 ViewModel,只需将一些 id/数据传递给新片段,创建自己的视图模型,并从其自己的视图模型查询片段的数据。

如果片段是某个流程/组(购物车/结帐/预订流程、多屏注册流程、viewpager 片段等)的一部分,并且逻辑足够通用,则在片段之间共享视图模型。在单活动架构中,我将这些流/流程放在其自己的根父片段中,该片段充当宿主并用于创建视图模型的范围。例如:

MainActivity ->
  -> RootAuthFragment
     -> SplashFragment (replace with below)
     -> LoginFragment (add to backstack with below or onsuccess login go to MainFragment)
     -> SignupFragment (onsuccess go to Main)
  -> MainFragment (replace with RootAuthFragment)
Run Code Online (Sandbox Code Playgroud)

在上述场景中,您可以在具有 RootAuthFragment 范围的登录和注册屏幕之间共享视图模型。如果您有一个多屏幕注册过程,那么您可以将其移动到单独的根片段中,并为注册流程创建一个单独的视图模型。

捆绑与视图模型:

捆绑包用于传递一些值。所以,就用它吧。我通常使用包来传递原始数据类型或枚举,并基于此从视图模型(通过 android 房间或改造)查询实际数据,或者如果数据对象足够小,我将它们打包并传递它。

如果你有一个共享的 ViewModel 并且它正在成为一个神类并且做了很多不同的事情,那么这意味着这些片段需要单独的 ViewModel。不要仅仅为了数据而共享 ViewModel。共享用于公共/共享行为/数据/逻辑的 ViewModel(以对您的特定用例有意义的为准)


小智 -1

根据https://developer.android.com/topic/libraries/architecture/viewmodel状态

这种方法具有以下优点:

The activity does not need to do anything, or know anything about this communication.

Fragments don't need to know about each other besides the SharedViewModel contract. If one of the fragments disappears, the other one keeps working as usual.

Each fragment has its own lifecycle, and is not affected by the lifecycle of the other one. If one fragment replaces the other one, the UI continues to work without any problems.
Run Code Online (Sandbox Code Playgroud)