【问题标题】:Force Paging Library to make Api Request强制分页库发出 Api 请求
【发布时间】:2018-11-04 01:13:59
【问题描述】:

我已经成功实现了一个 PagedList.BoundaryCallback,它从“themoviedb”数据库加载即将上映的电影列表,并将响应保存到数据库中。 但它不能按照我想要的方式工作。由于请求返回即将上映的电影列表,因此响应经常更改。但如果我的数据库中已有数据,则不会调用 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();
}

}

【问题讨论】:

    标签: android pagination datasource android-room android-paging


    【解决方案1】:

    在存储库中,您可以查询数据库以检查数据是否旧,然后您可以启动异步网络调用,将结果直接写入数据库。由于正在观察数据库,绑定到LiveData&lt;PagedList&gt; 的 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);
                });
    }
    

    【讨论】:

    • 谢谢,这是个好主意。但我真正想要实现的是每次打开具有可用互联网连接的应用时都从网络加载数据。
    • 这实际上更简单,您只需在 getUpcomingLiveData() 中返回新数据源之前清除数据库即可。 BoundaryCallback 负责获取新数据。
    • 如果您想在显示现有数据时加载新数据,您必须创建并传递一个指示加载状态的 LiveData,当重新加载完成时,只需更新您的数据库并显示新数据源。跨度>
    猜你喜欢
    • 2022-08-23
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    相关资源
    最近更新 更多