分页库最初返回空列表

时间:2018-12-05 13:15:37

标签: java android android-architecture-components android-jetpack android-paging

我正在使用Paging库对从服务器中检索到的项目列表进行分页。最初,在加载我的片段时,它将返回一个空列表。但是在更改了片段并返回到该片段之后,我可以看到列表已加载。调试后,我看到实际上是在提取数据,但是一个空列表传递给了我的片段。

ItemDataSource:

@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, Item> callback) {
    apiService.getItems(OFFSET)
    .enqueue(new Callback<ItemWrapper>() {
        @Override
        public void onResponse(@NonNull Call<ItemWrapper> call,@NonNull Response<ItemWrapper> response) {
            callback.onResult(response.body().getItems(), null, OFFSET + 25);
        }

        @Override
        public void onFailure(@NonNull Call<ItemWrapper> call,@NonNull Throwable t) {
            t.printStackTrace();
        }
    });
}

@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Item> callback) {

}

@Override
public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Item> callback) {
    apiService.getItems(params.key)
            .enqueue(new Callback<ItemWrapper>() {
                @Override
                public void onResponse(@NonNull Call<ItemWrapper> call,@NonNull Response<ItemWrapper> response) {
                    Integer key = response.body().getItems().isEmpty() ? null : params.key + 25;
                    callback.onResult(response.body().getItems(), key);
                }

                @Override
                public void onFailure(@NonNull Call<ItemWrapper> call,@NonNull Throwable t) {
                    t.printStackTrace();
                }
            });
}

ItemDataSourceFactory:

@Override
public DataSource create() {
    ItemDataSource itemDataSource = new ItemDataSource();
    itemLiveDataSource.postValue(itemDataSource);
    return itemDataSource;
}

public MutableLiveData<ItemDataSource> getItemLiveDataSource() {
    return itemLiveDataSource;
}

ItemViewModel:

private LiveData<ItemDataSource> liveDataSource;
private LiveData<PagedList<Item>> itemPagedList;

private ItemViewModel(Application application) {
    ItemDataSourceFactory factory = new ItemDataSourceFactory();
    liveDataSource = factory.getItemLiveDataSource();

    PagedList.Config config = (new PagedList.Config.Builder())
                .setEnablePlaceholders(false)
                .setPageSize(ItemDataSource.LIMIT).build();

    itemPagedList = (new LivePagedListBuilder(factory, config)).build();
}

public LiveData<PagedList<Item>> getItems() {
    return itemPagedList;
}

片段:

ItemViewModel itemViewModel = ViewModelProviders.of(this).get(ItemViewModel.class);
itemViewModel.getItems.observe(this, items -> {
    adapter.submitList(items);
})

5 个答案:

答案 0 :(得分:3)

不确定100%,但是我认为这是因为您正在运行异步请求。尝试将其更改为像loadInitial()那样request.execute()同步运行

答案 1 :(得分:2)

我也曾经遇到过这个问题,但我仍然无法弄清楚为什么它不适用于某些片段。我发现的解决方案更像是快速粗略的解决方案,是将片段加载两次。

答案 2 :(得分:1)

Yassin Ajdi是对的。 loadinitial()在创建PagedList的同一线程上立即调用。由于您的API是异步的,因此该方法首次运行为空

答案 3 :(得分:0)

如果像我一样,有人在loadInitial中使用异步RxJava / Kotlin调用。经过数小时的痛苦之后,我终于找到了解决方案。

我尝试在Observer方法中使用延迟的处理程序(500毫秒),但它善变,不能在每种情况下都起作用。无论我有多少尝试使用setFetcher和Rx observeOn使其同步,都无法始终如一地工作。

我的解决方案是在Observable中使用.blockingSubscribe。我的数据提取程序正在使用一个套接字库,该套接字库具有自己的并发性,超出了我的范围,因此我无法保证可以按分页的要求使该过程完全同步。 (此过程需要更好的IMO文档)。无论如何,这是我的解决方案,希望它可以帮助遇到同样问题的其他人:

    override fun loadInitial(
            params: LoadInitialParams<Int>,
            callback: LoadInitialCallback<Int, ResultItem>
    ) {
       mySocketClientRxRequest()
                .subscribe ({
                    callback.onResult(it.resultItems 1, 2)
                },{
                    it.printStackTrace()
                })
    }

    override fun loadInitial(
            params: LoadInitialParams<Int>,
            callback: LoadInitialCallback<Int, ResultItem>
    ) {
       mySocketClientRxRequest()
                .blockingSubscribe ({
                    callback.onResult(it.resultItems 1, 2)
                },{
                    it.printStackTrace()
                })
    }

答案 4 :(得分:0)

就像我在 loadInitial 中异步加载数据的问题一样,但是在调用回调时数据没有到达适配器。

只需从以下位置更新库版本即可解决 androidx.paging:paging-runtime-ktx:2.1.2androidx.paging:paging-runtime-ktx:3.0.0