最近我正在尝试这个:
我有一个由数据源支持的作业列表(我正在使用分页库),并且作业列表中的每个项目都有一个保存按钮,并且该保存按钮将数据库中作业的状态从未保存更新为已保存(反之亦然)一旦更新,它就会使数据源失效,现在失效应该会导致当前页面立即重新加载,但这种情况并没有发生。
我检查了数据库中的值,它们实际上已更新,但用户界面的情况并非如此。
Code:
public class JobsPagedListProvider {
private JobListDataSource<JobListItemEntity> mJobListDataSource;
public JobsPagedListProvider(JobsRepository jobsRepository) {
mJobListDataSource = new JobListDataSource<>(jobsRepository);
}
public LivePagedListProvider<Integer, JobListItemEntity> jobList() {
return new LivePagedListProvider<Integer, JobListItemEntity>() {
@Override
protected DataSource<Integer, JobListItemEntity> createDataSource() {
return mJobListDataSource;
}
};
}
public void setQueryFilter(String query) {
mJobListDataSource.setQuery(query);
}
}
这是我的自定义数据源:
public class JobListDataSource<T> extends TiledDataSource<T> {
private final JobsRepository mJobsRepository;
private final InvalidationTracker.Observer mObserver;
String query = "";
@Inject
public JobListDataSource(JobsRepository jobsRepository) {
mJobsRepository = jobsRepository;
mJobsRepository.setJobListDataSource(this);
mObserver = new InvalidationTracker.Observer(JobListItemEntity.TABLE_NAME) {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
jobsRepository.addInvalidationTracker(mObserver);
}
@Override
public boolean isInvalid() {
mJobsRepository.refreshVersionSync();
return super.isInvalid();
}
@Override
public int countItems() {
return DataSource.COUNT_UNDEFINED;
}
@Override
public List<T> loadRange(int startPosition, int count) {
return (List<T>) mJobsRepository.getJobs(query, startPosition, count);
}
public void setQuery(String query) {
this.query = query;
}
}
以下是 JobsRepository 中将作业从未保存更新为已保存的代码:
public void saveJob(JobListItemEntity entity) {
Completable.fromCallable(() -> {
JobListItemEntity newJob = new JobListItemEntity(entity);
newJob.isSaved = true;
mJobDao.insert(newJob);
Timber.d("updating entity from " + entity.isSaved + " to "
+ newJob.isSaved); //this gets printed in log
//insertion in db is happening as expected but UI is not receiving new list
mJobListDataSource.invalidate();
return null;
}).subscribeOn(Schedulers.newThread()).subscribe();
}
这是作业列表的比较逻辑:
private static final DiffCallback<JobListItemEntity> DIFF_CALLBACK = new DiffCallback<JobListItemEntity>() {
@Override
public boolean areItemsTheSame(@NonNull JobListItemEntity oldItem, @NonNull JobListItemEntity newItem) {
return oldItem.jobID == newItem.jobID;
}
@Override
public boolean areContentsTheSame(@NonNull JobListItemEntity oldItem, @NonNull JobListItemEntity newItem) {
Timber.d(oldItem.isSaved + " comp with" + newItem.isSaved);
return oldItem.jobID == newItem.jobID
&& oldItem.jobTitle.compareTo(newItem.jobTitle) == 0
&& oldItem.isSaved == newItem.isSaved;
}
};
JobRepository中的JobListDataSource(下面仅提及相关部分):
public class JobsRepository {
//holds an instance of datasource
private JobListDataSource mJobListDataSource;
//setter
public void setJobListDataSource(JobListDataSource jobListDataSource) {
mJobListDataSource = jobListDataSource;
}
}
JobsRepository 中的 getJobs() :
public List<JobListItemEntity> getJobs(String query, int startPosition, int count) {
if (!isJobListInit) {
Observable<JobList> jobListObservable = mApiService.getOpenJobList(
mRequestJobList.setPageNo(startPosition/count + 1)
.setMaxResults(count)
.setSearchKeyword(query));
List<JobListItemEntity> jobs = mJobDao.getJobsLimitOffset(count, startPosition);
//make a synchronous network call since we have no data in db to return
if(jobs.size() == 0) {
JobList jobList = jobListObservable.blockingSingle();
updateJobList(jobList, startPosition);
} else {
//make an async call and return cached version meanwhile
jobListObservable.subscribe(new Observer<JobList>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(JobList jobList) {
updateJobList(jobList, startPosition);
}
@Override
public void onError(Throwable e) {
Timber.e(e);
}
@Override
public void onComplete() {
}
});
}
}
return mJobDao.getJobsLimitOffset(count, startPosition);
}
更新 jobsRepository 中的 JobList:
private void updateJobList(JobList jobList, int startPosition) {
JobListItemEntity[] jobs = jobList.getJobsData();
mJobDao.insert(jobs);
mJobListDataSource.invalidate();
}