java MVVM的改进如何处理存储库中的大量实时数据?
我将按照本教程介绍如何使用MVVM进行改装
https://medium.com/@ronkan26/viewmodel-using-retrofit-mvvm-architecture-f759a0291b49
用户在存储库类中放置MutableLiveData的位置:
public class MovieRepository {
private static final ApiInterface myInterface;
private final MutableLiveData<EntityMovieOutputs> listOfMovies = new MutableLiveData<>();
private static MovieRepository newsRepository;
public static MovieRepository getInstance(){
if (newsRepository == null){
newsRepository = new NewsRepository();
}
return movieRepository;
}
public MovieRepository(){
myInterface = RetrofitService.getInterface();
}
我正在构建一个简单的应用程序,我注意到我的repository类很快被许多可变的LiveData对象填充。这实际上是实现MVVM、LiveData和存储库模式的正确方法吗
编辑1:\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
我创建了一个AdminLiveData
对象,它只保存LiveData和getter
但是,如何获得对AdminRepo
类中ViewModel
的引用,以便在改造网络调用完成时通知ViewModel中的LiveData
private AdminService adminService;
public AdminRepo(Application application) {
BaseApplication baseApplication = (BaseApplication) application;
RetrofitClient client = baseApplication.getRetrofitClient();
adminService = client.getRetrofit().create(AdminService.class);
//AdminViewModel viewModel = (AdminViewModel) ....
// Not sure how to get reference to the viewmodel here so I can get the
// LiveData object and call postValue after the retrofit calls
}
public void getFirstPageMembers(int offset, int limit) {
adminService.getUsersPaginitation(offset, limit).enqueue(new Callback<List<UserInfo>>() {
@Override
public void onResponse(@NonNull Call<List<UserInfo>> call, @NonNull Response<List<UserInfo>> response) {
if (response.body() != null) {
//firstPageLiveData.postValue(response.body());
//Since I create the LiveData inside the ViewModel class
//instead, how do I get reference to the ViewModel's LiveData?
}
}
@Override
public void onFailure(@NonNull Call<List<UserInfo>> call, @NonNull Throwable t) {
//firstPageLiveData.postValue(null);
}
});
}
该AdminViewModel
的:
public class AdminActivityViewModel extends AndroidViewModel {
private AdminRepo repo;
private AdminLiveData adminLiveData = new AdminLiveData();
public AdminActivityViewModel(@NonNull Application application) {
super(application);
repo = new AdminRepo(application);
}
如何从AdminRepo
类内部获取对AdminViewModel
的引用
# 1 楼答案
您正在寻找的解决方案取决于应用程序的设计方式。您可以尝试以下几种方法:
LiveData<ScreenState>
,你只需要映射你的实体李>此外,您可以使用coroutines with retrofit,因为现在推荐使用协同路由来处理后台操作,如果您想尝试一下,还可以使用Kotlin支持
此外,这些链接可能有助于您探索不同的体系结构或解决方案来处理问题architecture-components-samples或architecture-samples(不过主要使用kotlin)
# 2 楼答案
存储库和视图模型
android项目中的存储库对象应该被视为通向外部世界的网关。与持久性设施(网络、SQLite、共享Pref)的通信在此层中进行。因此,传入的数据不应该符合android环境。例如,传入DTO中的字符串日期字段应使用本地日期时间转换为日期对象,您可能需要将来自服务器的数据保存到本地数据库。此外,其他与数据相关的任务也可以在这一层中执行,比如在内存中缓存
ViewModels表示用户界面中显示的数据。该层中的数据应准备好显示在屏幕上。例如,一个视图可能需要来自两个不同HTTP请求的数据,您应该在此层中合并传入的数据。(不过,您可以进一步分离责任。如果这两个请求是单个任务或目的的一部分,您可以在用例层中执行此操作。)从android的角度来看,视图模型有更多的责任,比如防止数据在配置更改中被破坏。在视图模型中,建议使用LiveData将数据显示到视图层。这是因为LiveData保留了数据的最后状态,并且它知道视图层的生命周期(如果使用得当的话)
存储库和ViewModel之间的通信
首先,存储库层不能意识到任何视图模型的存在,因此不应在存储库层中保留视图模型的引用。有一些原因,
当然,我们需要对视图模型进行某种引用,以便在请求完成时通知它,但我们应该以系统的方式隐式地这样做,而不是直接引用
回调:这是一种将数据发送回视图模型的老式方式。在代码库中广泛使用回调会导致不需要的回调地狱。此外,结构化取消机制很难使用回调实现
LiveData:乍一看,它似乎非常适合此用途,但事实并非如此。原因如下:
在您的情况下,这是一种特别糟糕的做法,因为HTTP请求不应更改存储库对象的状态。您使用LiveData作为一种缓存,但是没有这样的要求,所以您应该避免这样做。尽管如此,如果您需要在repo中使用LiveData,您应该将MutableLiveData作为参数传递给您的请求方法,以便您可以通过该LiveData发布响应,或者在请求方法中返回LiveData
RxJava:这是选项之一。它支持一次性请求(单个)、热流(主题)和冷流(可观察)。它支持st以某种方式进行结构化取消(可合成)。它有一个稳定的API,多年来一直被广泛使用。它还使许多不同的网络操作变得更容易,如并行请求、顺序请求、数据操作、线程切换等
协同程序:这是另一种选择,在我看来是最好的选择。虽然它的API不是完全稳定的,但我已经在许多不同的项目中使用过它,我没有看到任何问题。它支持一次性请求(挂起功能)、热流(通道和状态流)和冷流(流)。它在需要复杂数据流的项目中非常有用。它是Kotlin中的内置功能,适用于所有操作员。它以一种非常优雅的方式支持结构化并发。它有许多不同的操作符函数,与RxJava相比,实现新的操作符函数更容易。它还具有用于ViewModel的有用扩展函数
总而言之,存储库层是传入数据的网关,正如我前面提到的,这是您操作数据以符合应用程序要求的第一个地方。可以在该层中完成的操作可以很快列出,如映射传入数据、决定从何处获取数据(本地或远程源)以及缓存。有许多选项可以将数据传递回请求数据的类,但正如我前面所解释的,RxJava和协同路由比其他的要好。在我看来,如果你对这两个方面都不熟悉,那就把你的精力放在合作上