强制分页库发出 Api 请求
Force Paging Library to make Api Request
我已经成功实现了 PagedList.BoundaryCallback,它从 "themoviedb" 数据库加载即将上映的电影列表,并将响应保存到数据库中。
但它没有按照我想要的方式工作。由于请求 return 即将上映的电影列表,因此响应经常更改。但是,如果我的数据库中已有数据,则不会调用 onZeroItemsLoaded() 方法。
我的问题是,如何强制数据源或此边界回调始终发出 api 请求,并从网络刷新数据库的内容?
public class UpcomingMoviesBoundaryCallback extends PagedList.BoundaryCallback<MovieListItemEntity> {
public static final String TAG = UpcomingMoviesBoundaryCallback.class.getSimpleName();
private UpcomingMoviesRepository upcomingMoviesRepository;
private int page = 1;
public UpcomingMoviesBoundaryCallback(UpcomingMoviesRepository upcomingMoviesRepository) {
this.upcomingMoviesRepository = upcomingMoviesRepository;
}
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
Log.d(TAG, "onZeroItemsLoaded: ");
load();
}
@Override
public void onItemAtEndLoaded(@NonNull MovieListItemEntity itemAtEnd) {
super.onItemAtEndLoaded(itemAtEnd);
Log.d(TAG, "onItemAtEndLoaded: ");
load();
}
@SuppressLint("CheckResult")
private void load() {
upcomingMoviesRepository.getUpcoming(page)
.doOnSuccess(result -> {
upcomingMoviesRepository.saveUpcomingMovies(result);
page = result.getPage() + 1;
})
.subscribeOn(Schedulers.io())
.subscribe(result -> {
Log.d(TAG, "load: " + result);
}, error -> {
Log.d(TAG, "load: error", error);
});
}
}
public class UpcomingMoviesRepositoryImpl implements UpcomingMoviesRepository {
private static final String TAG = UpcomingMoviesRepository.class.getSimpleName();
private MovieResponseMapper movieResponseMapper = new MovieResponseMapper();
private MovieAppApi mMovieAppApi;
private UpcomingDao mUpcomingDao;
public UpcomingMoviesRepositoryImpl(MovieAppApi mMovieAppApi, UpcomingDao mUpcomingDao) {
this.mMovieAppApi = mMovieAppApi;
this.mUpcomingDao = mUpcomingDao;
}
@Override
public Single<MovieListResponse> getUpcoming(int page) {
return mMovieAppApi.upcoming(page);
}
@Override
public Single<MovieListResponse> getUpcoming() {
return mMovieAppApi.upcoming();
}
@Override
public void saveUpcomingMovies(MovieListResponse movieListResponse) {
Executors.newSingleThreadExecutor().execute(() -> {
long[] inseted = mUpcomingDao.save(movieResponseMapper.map2(movieListResponse.getResults()));
Log.d(TAG, "saveUpcomingMovies: " + inseted.length);
});
}
@Override
public LiveData<PagedList<MovieListItemEntity>> getUpcomingLiveData() {
PagedList.Config config = new PagedList.Config.Builder()
.setEnablePlaceholders(true)
.setPageSize(12)
.build();
DataSource.Factory<Integer, MovieListItemEntity> dataSource = mUpcomingDao.upcoming();
LivePagedListBuilder builder =
new LivePagedListBuilder(dataSource, config)
.setBoundaryCallback(new UpcomingMoviesBoundaryCallback(this));
return builder.build();
}
}
在存储库中,您可以查询数据库以检查数据是否旧,然后您可以启动异步网络调用,将结果直接写入数据库。因为正在观察数据库,绑定到 LiveData<PagedList>
的 UI 将自动更新以说明新数据集。
@Override
public LiveData<PagedList<MovieListItemEntity>> getUpcomingLiveData() {
if(mUpcomingDao.isDatasetValid()) //Check last update time or creation date and invalidate data if needed
upcomingMoviesRepository.getUpcoming()
.doOnSuccess(result -> {
upcomingMoviesRepository.clearUpcomingMovies()
upcomingMoviesRepository.saveUpcomingMovies(result);
})
.subscribeOn(Schedulers.io())
.subscribe(result -> {
Log.d(TAG, "load: " + result);
}, error -> {
Log.d(TAG, "load: error", error);
});
}
我已经成功实现了 PagedList.BoundaryCallback,它从 "themoviedb" 数据库加载即将上映的电影列表,并将响应保存到数据库中。 但它没有按照我想要的方式工作。由于请求 return 即将上映的电影列表,因此响应经常更改。但是,如果我的数据库中已有数据,则不会调用 onZeroItemsLoaded() 方法。 我的问题是,如何强制数据源或此边界回调始终发出 api 请求,并从网络刷新数据库的内容?
public class UpcomingMoviesBoundaryCallback extends PagedList.BoundaryCallback<MovieListItemEntity> {
public static final String TAG = UpcomingMoviesBoundaryCallback.class.getSimpleName();
private UpcomingMoviesRepository upcomingMoviesRepository;
private int page = 1;
public UpcomingMoviesBoundaryCallback(UpcomingMoviesRepository upcomingMoviesRepository) {
this.upcomingMoviesRepository = upcomingMoviesRepository;
}
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
Log.d(TAG, "onZeroItemsLoaded: ");
load();
}
@Override
public void onItemAtEndLoaded(@NonNull MovieListItemEntity itemAtEnd) {
super.onItemAtEndLoaded(itemAtEnd);
Log.d(TAG, "onItemAtEndLoaded: ");
load();
}
@SuppressLint("CheckResult")
private void load() {
upcomingMoviesRepository.getUpcoming(page)
.doOnSuccess(result -> {
upcomingMoviesRepository.saveUpcomingMovies(result);
page = result.getPage() + 1;
})
.subscribeOn(Schedulers.io())
.subscribe(result -> {
Log.d(TAG, "load: " + result);
}, error -> {
Log.d(TAG, "load: error", error);
});
}
}
public class UpcomingMoviesRepositoryImpl implements UpcomingMoviesRepository {
private static final String TAG = UpcomingMoviesRepository.class.getSimpleName();
private MovieResponseMapper movieResponseMapper = new MovieResponseMapper();
private MovieAppApi mMovieAppApi;
private UpcomingDao mUpcomingDao;
public UpcomingMoviesRepositoryImpl(MovieAppApi mMovieAppApi, UpcomingDao mUpcomingDao) {
this.mMovieAppApi = mMovieAppApi;
this.mUpcomingDao = mUpcomingDao;
}
@Override
public Single<MovieListResponse> getUpcoming(int page) {
return mMovieAppApi.upcoming(page);
}
@Override
public Single<MovieListResponse> getUpcoming() {
return mMovieAppApi.upcoming();
}
@Override
public void saveUpcomingMovies(MovieListResponse movieListResponse) {
Executors.newSingleThreadExecutor().execute(() -> {
long[] inseted = mUpcomingDao.save(movieResponseMapper.map2(movieListResponse.getResults()));
Log.d(TAG, "saveUpcomingMovies: " + inseted.length);
});
}
@Override
public LiveData<PagedList<MovieListItemEntity>> getUpcomingLiveData() {
PagedList.Config config = new PagedList.Config.Builder()
.setEnablePlaceholders(true)
.setPageSize(12)
.build();
DataSource.Factory<Integer, MovieListItemEntity> dataSource = mUpcomingDao.upcoming();
LivePagedListBuilder builder =
new LivePagedListBuilder(dataSource, config)
.setBoundaryCallback(new UpcomingMoviesBoundaryCallback(this));
return builder.build();
}
}
在存储库中,您可以查询数据库以检查数据是否旧,然后您可以启动异步网络调用,将结果直接写入数据库。因为正在观察数据库,绑定到 LiveData<PagedList>
的 UI 将自动更新以说明新数据集。
@Override
public LiveData<PagedList<MovieListItemEntity>> getUpcomingLiveData() {
if(mUpcomingDao.isDatasetValid()) //Check last update time or creation date and invalidate data if needed
upcomingMoviesRepository.getUpcoming()
.doOnSuccess(result -> {
upcomingMoviesRepository.clearUpcomingMovies()
upcomingMoviesRepository.saveUpcomingMovies(result);
})
.subscribeOn(Schedulers.io())
.subscribe(result -> {
Log.d(TAG, "load: " + result);
}, error -> {
Log.d(TAG, "load: error", error);
});
}