I'm developing an android app for showing a list of products stored in a server. I'm using Paging 3 lib with Guava/LiveData. When debugging, i found that the method onChanged from LiveData is always called before the PagingSource fetch data from server and never more.
My PagingSource class:
public class ProductsPagingSource extends ListenableFuturePagingSource<Integer, Product> {
ProductsRepository productsRepository;
Integer initialLoadSize = 0;
public ProductsPagingSource(ProductsRepository productsRepository) {
this.productsRepository = productsRepository;
}
@Nullable
@Override
public Integer getRefreshKey(@NonNull PagingState<Integer, Product> pagingState)
{
return null;
}
@NonNull
@Override
public ListenableFuture<LoadResult<Integer, Product>> loadFuture(@NonNull LoadParams<Integer> loadParams) {
Integer nextPageNumber = loadParams.getKey();
if (nextPageNumber == null) {
nextPageNumber = 1;
initialLoadSize = loadParams.getLoadSize();
}
Integer offSet = 0;
if(nextPageNumber == 2) {
offSet = initialLoadSize;
}
else {
offSet = ((nextPageNumber - 1) * loadParams.getLoadSize()) + (initialLoadSize - loadParams.getLoadSize());
}
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
Integer finalOffSet = offSet;
Integer finalNextPageNumber = nextPageNumber;
ListenableFuture<LoadResult<Integer, Product>> lf = service.submit(new Callable<LoadResult<Integer, Product>>() {
@Override
public LoadResult<Integer, Product> call() {
List<Product> productsList = null;
productsList = productsRepository.loadProducts(loadParams.getLoadSize(), finalOffSet);
Integer nextKey = null;
if(productsList.size() >= loadParams.getLoadSize()) {
nextKey = finalNextPageNumber + 1;
}
return new LoadResult.Page<Integer, Product>(productsList,
null,
nextKey);
}
});
return lf;
}
}
The ViewModel class:
public class HomeViewModel extends AndroidViewModel {
LiveData<PagingData<Product>> productsLd;
public HomeViewModel(@NonNull Application application) {
super(application);
ProductsRepository productsRepository = new ProductsRepository(getApplication());
CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(this);
Pager<Integer, Product> pager = new Pager(new PagingConfig(10), () -> new ProductsPagingSource(productsRepository));
productsLd = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), viewModelScope);
}
public LiveData<PagingData<Product>> getProductsLd() {
return productsLd;
}
}
Then, on method onCreate from HomeActivity, LiveData is observed:
myAdapter = new MyAdapter(this, new ProductComparator());
HomeViewModel homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
LiveData<PagingData<Product>> productsLd = homeViewModel.getProductsLd();
productsLd.observe(this, new Observer<PagingData<Product>>() {
@Override
public void onChanged(PagingData<Product> productPagingData) {
myAdapter.submitData(getLifecycle(),productPagingData);
}
});
onChanged is immediately called after the LiveData is obtained from ViewModel and before loadFuture from ProductsPagingSource is called, so the PagingData delivered is empty. Method loadFuture from ProductsPagingSource is called and the data is fetched correctly from server, but LiveData never triggers onChanged.
Can someone help me? Thanks in advance!