データベースからキャッシュされたバージョンのデータをロードする必要があり、同時にサーバーに新しいデータを要求したいのですが、これをページごとに実行したいと思います。したがって、たとえば最初のページの場合、最初のページの新しいデータのみを要求しながら、データベースからの最初のページのデータのキャッシュバージョンを表示したいと思います。ページングライブラリ
を使用してこれを実現したいと思います。ページの読み込み要求をインターセプトするのに役立つカスタムデータソースを作成しようとしました。これは、必要なページ番号と制限を使用してネットワーク呼び出しを行うために使用しましたが、dbからキャッシュされたバージョンを返しましたが、問題はネットワークから新しいデータを取得した後です。データベースですが、それらの更新は反映されません。
(Invalidation Trackerを使用して変更がないかテーブル全体が監視されており、テーブルが無効になるたびにデータソースが無効になると思います。そのトラッカーもデータソースに追加しましたが、それでも機能しません。その無効化を確認できました。 JobDaoでLivePagedListProvidergetJobs()を一時的に作成し、生成された実装を確認することによるトラッカーのこと)
コード:
public class JobListDataSource<T> extends TiledDataSource<T> {
private final JobsRepository mJobsRepository;
private final InvalidationTracker.Observer mObserver;
String query = "";
public JobListDataSource(JobsRepository jobsRepository) {
mJobsRepository = jobsRepository;
mObserver = new InvalidationTracker.Observer(JobEntity.TABLE_NAME) {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
jobsRepository.addInvalidationTracker(mObserver);
}
@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;
}
}
ジョブリポジトリ機能:
public List<JobEntity> getJobs(String query, int startPosition, int count) {
if (!isJobListInit) {
JobList jobList = mApiService.getOpenJobList(
mRequestJobList.setPageNo(startPosition/count + 1)
.setMaxResults(count)
.setSearchKeyword(query)
).blockingSingle();
mJobDao.insert(jobList.getJobsData());
}
return mJobDao.getJobs(startPosition, count);
}
public void addInvalidationTracker(InvalidationTracker.Observer observer) {
mAppDatabase.getInvalidationTracker().addObserver(observer);
}
それで、なぜそれが機能しなかったのか理解しました、私の終わりに間違いがありました、私はJobsRepositoryのJobDaoのgetJobsメソッドに間違ったパラメーターを渡していました。
JobDaoのgetJobsメソッドは次のようになります。
@Query("SELECT * FROM jobs ORDER BY jobID ASC LIMIT :limit OFFSET :offset")
List<JobEntity> getJobs(int limit, int offset);
また、JobsRepositoryでのgetJobs()の呼び出しは次のようになります。
return mJobDao.getJobs(startPosition, count);
したがって、最初のパラメーターは制限であり、次のパラメーターはオフセットでしたが、私は逆に通過していました。
今ではそれは魅力のように機能します!
さらに、JobsRepositoryのgetJobs()に変更を加えました。最初にdbからデータを取得し、可能な場合は戻り、必要に応じてネットワークに非同期リクエストを送信します。dbで利用可能なデータがない場合は、ネットワークへの同期呼び出しを行い、ネットワークからデータを取得し、それを解析してdbに保存し、dbから最新のデータにアクセスして返します。したがって、関数は次のようになります。
//you can even refactor this code so that all the network related stuff is in one class and just call that method
public List<JobListItemEntity> getJobs(String query, int startPosition, int count) {
Observable<JobList> jobListObservable = mApiService.getOpenJobList(
mRequestJobList.setPageNo(startPosition / count + 1)
.setMaxResults(count)
.setSearchKeyword(query));
List<JobListItemEntity> jobs = mJobDao.getJobsLimitOffset(count, startPosition);
//no data in db, make a synchronous call to network to get the data
if (jobs.size() == 0) {
JobList jobList = jobListObservable.blockingSingle();
updateJobList(jobList, startPosition, false);
} else if (shouldFetchJobList(jobs)) {
//data available in db, so show a cached version and make async network call to update data as this data is no longer fresh
jobListObservable.subscribe(new Observer<JobList>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(JobList jobList) {
updateJobList(jobList, startPosition, true);
}
@Override
public void onError(Throwable e) {
Timber.e(e);
}
@Override
public void onComplete() {
}
});
}
return mJobDao.getJobsLimitOffset(count, startPosition);
}
updateJobList()コード:
private void updateJobList(JobList jobList, int startPosition, boolean performInvalidation) {
JobListItemEntity[] jobs = jobList.getJobsData();
Date currentDate = Calendar.getInstance().getTime();
//tracks when this item was inserted in db, used in calculating whether data is stale
for (int i = 0; i < jobs.length; i++) {
jobs[i].insertedAt = currentDate;
}
mJobDao.insert(jobs);
if (performInvalidation) {
mJobListDataSource.invalidate();
}
}
(また、JobDaoのgetJobs()の名前をgetJobsLimitOffset()に変更しました。これにより、読みやすくなり、ページングライブラリによってメソッドが生成される方法でもあります)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加