MVVM - 如何跨多个 ViewModel 共享单个存储库 class
MVVM - How to share a single repository class across multiple ViewModels
我有多个访问单个存储库的视图模型(一个 activity 和其余片段)。
AdminActivityViewModel
AdminListUsersViewModel
AdminUserTransactionsViewModel
...还有一些
我的 AdminRepo
class 有多个构造函数,因此我可以从 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
class?
我考虑过使用 .getInstance()
方法使我的 AdminRepo
class 成为单例,但我收到了很多关于 Repository classes 应该如何处理的自相矛盾的帖子不是静态的或单例的,这让我对我应该做什么感到非常困惑。
如果所有视图模型同时存在,那么存储库不保留任何状态,您可以共享相同的存储库实例并为每个视图模型提供该实例。然而这里没有魔法的地方——如果你创建了一个存储库的实例,你必须保留对它的引用,这样你就可以将相同的对象传递给其他视图模型。
首先你需要让你的视图模型接受外部依赖(I\d推荐看dependency injection模式)
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
以便您的存储库与 activity.
一样长
现在,如果这些视图模型具有不同的生命周期并且它们不重叠,则完全可以为它们中的每一个创建一个新实例。当你不再需要它们时,你不会想在内存中保留不必要的对象。
我有多个访问单个存储库的视图模型(一个 activity 和其余片段)。
AdminActivityViewModel
AdminListUsersViewModel
AdminUserTransactionsViewModel
...还有一些
我的 AdminRepo
class 有多个构造函数,因此我可以从 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
class?
我考虑过使用 .getInstance()
方法使我的 AdminRepo
class 成为单例,但我收到了很多关于 Repository classes 应该如何处理的自相矛盾的帖子不是静态的或单例的,这让我对我应该做什么感到非常困惑。
如果所有视图模型同时存在,那么存储库不保留任何状态,您可以共享相同的存储库实例并为每个视图模型提供该实例。然而这里没有魔法的地方——如果你创建了一个存储库的实例,你必须保留对它的引用,这样你就可以将相同的对象传递给其他视图模型。
首先你需要让你的视图模型接受外部依赖(I\d推荐看dependency injection模式)
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
以便您的存储库与 activity.
现在,如果这些视图模型具有不同的生命周期并且它们不重叠,则完全可以为它们中的每一个创建一个新实例。当你不再需要它们时,你不会想在内存中保留不必要的对象。