我正在使用数据库设置作为事实的唯一来源来构建脱机优先应用程序。我正在使用Room来简化数据库处理,并使用LiveData来简化可观察的数据模式。
我还使用Retrofit进行用新数据填充数据库所需的任何网络调用。
我在Fragment中设置了一个观察者,如下所示:
private void setUpObserver() {
tfViewModel = ViewModelProviders.of(getActivity()).get(TFViewModel.class);
tfViewModel.getAllPosts().observe(getActivity(),
newPosts -> {
if (newPosts != null && newPosts.size() > 0) {
lottieAnimationView.setVisibility(View.INVISIBLE);
mPostsAdapter.updateItems(newPosts);
}
});
tfViewModel.fetchNextData(currentPage);
}
当我的应用程序首次启动时,我会使用Room回调来删除数据库中的每个表,以便每次都获取新数据。 (用于测试。这要优于脱机优先的经验,绝不能在生产中进行。)
无论如何,因此,当它第一次启动时,它会调用viewmodel的fetchNextData
方法,该方法又要求存储库获取数据。
这是我的ViewModel:
public class TFViewModel extends AndroidViewModel {
private TFRepository mRepository;
private LiveData<List<Post>> mPostList;
public TFViewModel(Application application) {
super(application);
mRepository = new TFRepository(application);
mPostList = mRepository.getAllPosts();
}
public LiveData<List<Post>> getAllPosts() {
return mPostList;
}
public void fetchNextData(int page) {
mRepository.fetchNextPosts(page);
}
}
在存储库中,我使用我的DAO将帖子插入数据库。为了获取新数据,我使用服务类为我获取新数据。当fetch调用返回时,我使用AsyncTask将新帖子插入到数据库中。 (为简洁起见,省略了详细信息):
public class TFRepository {
private PostDao postDao;
private LiveData<List<Post>> postList;
private RetrofitSingleton retrofitSingleton;
public TFRepository(Application application) {
TFRoomDatabase db = TFRoomDatabase.getDatabase(application);
postDao = db.postDao();
retrofitSingleton = RetrofitSingleton.getInstance(application.getApplicationContext());
postList = postDao.getAllPosts();
}
public LiveData<List<Post>> getAllPosts() {
return postList;
}
public void fetchNextPosts(int page) {
getPostList(page);
}
private void getPostList(int page) {
APICaller.getInstance(retrofitSingleton).getFeed(page,
new NetworkResponseListener<BaseResponse<FeedResponse>>() {
@Override
public void onResponseReceived(BaseResponse<FeedResponse> feedResponseBaseResponse) {
if (feedResponseBaseResponse == null) return;
List<Post> posts = feedResponseBaseResponse.getData().getPosts();
new insertAllPostsAsyncTask(postDao).execute(posts);
}
@Override
public void onError(String errorMessage) {
}
});
}
}
我在片段中设置的OBSERVER 第一次获得一个空列表。 API调用返回第一页帖子,第二次收到10条帖子。视图被弹出。一切都很好。
问题:随着用户向下滚动,Fragment要求ViewModel获取更多数据。 ViewModel要求存储库获取新数据。 改造 通话进行并返回新数据。它被插入数据库中。 未通知观察者。我缺少什么?
注意:我不想使用 MutableLiveData
,因为我想将数据库保持为唯一的事实来源。另外,由于文档指出只要底层数据库发生更改,就会通知 LiveData ,因此我的实现应与LiveData一起使用。