2

I am trying to implement the new paging library from android architecture components. Basic functions are working fine but I need to add a retry function for loadRange() or loadAfter(). I need to retry these in case a network error occurs or if the device is offline. I already tried dataSource.invalidate() which throws away the whole data source which seems like a waste. Is there a way to do this?

Here is my code:

public class MyDataSource extends PositionalDataSource<Item> {

    ...

    @Override
    public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<Item> callback) {
        ArrayList<Item> items = executeCall(1, params.requestedLoadSize);

        if (items != null) {
            callback.onResult(items, 0, totalCount);
        } else {
            callback.onResult(new ArrayList<Item>(), 0);
        }
    }

    @Override
    public void loadRange(@NonNull LoadRangeParams params, @NonNull LoadRangeCallback<Item> callback) {
        ArrayList<Item> items = executeCall(params.startPosition, params.loadSize);

        if (items != null) {
            callback.onResult(items);
        } else {
            callback.onResult(new ArrayList<Item>());
        }
    }

    ...
}
  • Take a look at the [google-samples](https://github.com/googlesamples/android-architecture-components/blob/master/PagingWithNetworkSample/app/src/main/java/com/android/example/paging/pagingwithnetwork/reddit/repository/inMemory/byPage/PageKeyedSubredditDataSource.kt) . You can save the previous call's reference and call the same by calling the retry function. – insa_c Jul 24 '18 at 18:48
  • Thanks, I ended up using something like this. – Naveen Dissanayake Jul 25 '18 at 05:50

1 Answers1

1

The document says

A callback can be called only once, and will throw if called again. It is always valid for a DataSource loading method that takes a callback to stash the callback and call it later. This enables DataSources to be fully asynchronous, and to handle temporary, recoverable error states (such as a network error that can be retried).

Therefore, here is how you can implement

@Override
public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback<Item> callback) {
    ArrayList<Item> items = executeCall(1, params.requestedLoadSize);

    if (items != null) {
        callback.onResult(items, 0, totalCount);
    } else {
        //callback.onResult(new ArrayList<Item>());
        //instead of passing the result when error, just ignore it and pass the loading state to your UI to handle reload
        yourLoadingState.post(LOADING.ERROR);
    }
}

@Override
public void loadRange(@NonNull LoadRangeParams params, @NonNull LoadRangeCallback<Item> callback) {
    ArrayList<Item> items = executeCall(params.startPosition, params.loadSize);

    if (items != null) {
        callback.onResult(items);
    } else {
        //callback.onResult(new ArrayList<Item>());
        //instead of passing the result when error, just ignore it and pass the loading state to your UI to handle reload
        yourLoadingState.post(LOADING.ERROR);
    }
}

Hope it will help you solve the problem

Dennis Nguyen
  • 278
  • 2
  • 9