android - MVVM - 如何跨多个 ViewModel 共享单个存储库类
问题描述
我有多个视图模型可以访问单个存储库(一个活动和其余片段)。
AdminActivityViewModel
AdminListUsersViewModel
AdminUserTransactionsViewModel
......还有更多
我的AdminRepo
类有多个构造函数,因此我可以从 ViewModel 传递回调方法
public AdminRepo(Application application, AdminActivityCallback callback) {
this.callback = callback;
BaseApplication baseApplication = (BaseApplication) application;
RetrofitClient client = baseApplication.getRetrofitClient();
adminService = client.getRetrofit().create(AdminService.class);
SharedPrefManager sharedPref = SharedPrefManager.getInstance(application);
AuthHeader authHeader = new AuthHeader(
sharedPref.getIdToken(),
sharedPref.getIdClient(),
sharedPref.getUserEmail()
);
client.setAuthHeader(authHeader);
}
public AdminRepo(Application application, AdminListUsersCallback callback) {
//Exact same code in constructor as above ^
}
public AdminRepo(Application application, AdminUserTransactionsCallback callback) {
//Exact same code in constructor as above ^
}
在每一个中,ViewModels
我都在创建一个实例AdminRepo
(这可能是一个不好的做法),但我不知道如何改进它。
public class AdminActivityViewModel extends AndroidViewModel implements AdminActivityCallback
public AdminActivityViewModel(@NonNull Application application) {
super(application);
repo = new AdminRepo(application, this);
}
如何设计我的AdminRepo
和 ViewModel 以便它们共享一个存储库,而无需AdminRepo
每次都创建昂贵的类?
我考虑AdminRepo
过用一种方法让我的类成为单例.getInstance()
,但是我收到了很多关于存储库类不应该是静态或单例的自相矛盾的帖子,这让我对我应该做什么感到非常困惑。
解决方案
如果所有视图模型同时存在并且存储库不保留任何状态,您可以共享相同的存储库实例并为每个视图模型提供该实例。然而,这里没有魔法的地方——如果你创建了一个存储库的实例,你必须保留对它的引用,这样你就可以将相同的对象传递给其他视图模型。
首先你需要让你的视图模型接受外部依赖(我建议查看依赖注入模式)
YourViewModel( /* other dependencies ..., */ AdminRepo adminRepo)
一旦你有了它,你需要创建一个视图模型工厂。这篇文章很好地描述了它,但长话短说:实现ViewModelProvider.Factory
将保留您的存储库实例并使用它ViewModelProvider
来获取视图模型的实例。
通过此设置,您将控制您创建的实例以及如何创建其他视图模型。这可以通过使用依赖注入框架(Koin、dagger、hilt)实现自动化。如果您使用 Dagger 或Hilt(由 Google 推荐),那么您可以通过提供适当的注释将您的对象生命周期留在框架手中。让我们试试这个例子:
@Singleton
class MyRepository { ...
@HiltViewModel
class MyViewModel {
MyRepository repo;
@Inject MyViewModel(MyRepository repo) { ...
...
此代码将使您的存储库成为与您的应用程序生命周期相关联的单例。通常你不想这样做,因为即使你移动到不需要它的屏幕,对象也会存在于内存中。但是您可以使用@ActivityScoped
这样您的存储库就可以在活动中存活。
现在,如果这些视图模型具有不同的生命周期并且它们不重叠,那么为它们中的每一个创建一个新实例就完全没问题了。当您不再需要它们时,您不希望将不必要的对象保留在内存中。
推荐阅读
- python - 仅当我按下 alt 按钮时才会绘制 Tkinter 小部件
- javascript - 如何定义正确的接口并在 React 中循环数据?
- automation - 使用 Automation Anywhere 到达 Google 表格中具有值的最后一个单元格
- excel - 格式化 - 导出为 PDF - Excel VBA
- javascript - 从 mongodb 获取数据时,节点 js javascript 中的 Map.get() 总是返回 undefined
- python - 当给定两个数字在python中给出余数0时,我想打印一些东西。下面的代码是为了演示我想要的,但它没有用
- javascript - 在没有 Graphql 的情况下从 Gatsby src 文件夹中获取图像,同时仍然使用 Graphql 获取其他图像
- sql - 查询显示各部门工资最低的员工
- flutter - Flutter 构建报错:连接服务协议时出错:无法连接到 http://127.0.0.1:51234/v9-zOlh23aE=/
- java - 获取两个带分隔符的数字并打印总和