4

I have implementation of PositionalDataSource that defines loadInitial and loadRange. Paging works fine however under some boundary condition (likely related with loading next page in progress while exiting the screen) app crashes with androidx.paging.ContiguousPagedList$1.onPageError (ContiguousPagedList.java:153). However a per https://developer.android.com/reference/android/arch/paging/PositionalDataSource my source is not contiguous?

Crash occurs under ContiguousPagedList's onPageError, line with "todo":

public void onPageError(@PageResult.ResultType int resultType,
        @NonNull Throwable error, boolean retryable) {

   LoadState errorState = retryable ? LoadState.RETRYABLE_ERROR : LoadState.ERROR;

    if (resultType == PageResult.PREPEND) {
        mLoadStateManager.setState(LoadType.START, errorState, error);
    } else if (resultType == PageResult.APPEND) {
        mLoadStateManager.setState(LoadType.END, errorState, error);
    } else {
        // TODO: pass init signal through to *previous* list
        throw new IllegalStateException("TODO");
    }
}

My configuration is not using placeholders, and I'm not passing total count into onResult of LoadInitialCallback. Version of paging library is 2.1.1

Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
ror
  • 3,295
  • 1
  • 19
  • 27
  • I had a try-catch in `loadInitial` and `loadAfter` methods of my `PageKeyedDataSource` implementation. In in the catch I was calling `callback.onError(e)`. In order to prevent the app from crashing I removed the `callback.onError(e)` line. I know this is not a solution, but at least my app is not crashing randomly. – gianlucaparadise Feb 03 '20 at 05:45
  • 1
    @gianlucaparadise I kind of ended up with something similar but using live data. Will accept your answer if you post. – ror Feb 07 '20 at 13:25

2 Answers2

2

There is no good and clean solution at least for now(version 2.1.1).

ContiguousPagedList doesn't support error handling for initialization. You have to implement parallel streams for loading statuses and custom retry.

See the example in the official architecture components samples library. Yigit Boyar implemented few streams by returning custom Listing object from the repository.

data class Listing<T>(
        // the LiveData of paged lists for the UI to observe
        val pagedList: LiveData<PagedList<T>>,
        // represents the network request status to show to the user
        val networkState: LiveData<NetworkState>,
        // represents the refresh status to show to the user. Separate from networkState, this
        // value is importantly only when refresh is requested.
        val refreshState: LiveData<NetworkState>,
        // refreshes the whole data and fetches it from scratch.
        val refresh: () -> Unit,
        // retries any failed requests.
        val retry: () -> Unit)

See the implementation of data source here

Update

After many different tries, I end-up removing Jetpack from the core part of the architecture, and leave it only in view model, looks much cleaner for me now. You can read about it here

Community
  • 1
  • 1
VadzimV
  • 1,111
  • 12
  • 13
0

I experienced the same behaviour because I called callback.onError(e) when an exception happened in loadInitial and loadAfter methods of my PageKeyedDataSource implementation. In order to prevent the app from crashing I removed the callback.onError(e) line. I know this is not a solution, but at least my app is not crashing randomly.

Example code (Kotlin+coroutines incoming)

override fun loadInitial(params: LoadInitialParams<Long>, callback: LoadInitialCallback<Long, Beer>) {
    scope.launch {
        try {
            val response =
                BackendService.client.getBeers(
                    name = searchQueryNullable,
                    page = 1,
                    pageSize = params.requestedLoadSize
                )
            callback.onResult(response, 1, 2)
        } catch (e: Exception) {
            Log.e(tag, "Error loadInitial", e)
            // callback.onError(e) <-- this is the line that generates the crash: comment it
        }
    }
}
gianlucaparadise
  • 1,678
  • 20
  • 32
  • 1
    Thanks! Btw I found this one helpful too: https://www.slideshare.net/GaborVaradi3/paging-like-a-pro - the guy who wrote this is really cool. – ror Feb 07 '20 at 17:26
  • if I understand the library correctly however, this also means, that you're never going to be able to load another page, because the library stays in loading state ( `LoadState.LOADING` ). So far I have not seen any way to get paging library out of that state and official google example uses very clumsy method for retrying the same request by user, which is not easy to apply. – Lukas1 Feb 19 '20 at 13:24