1

I am trying to implement "Retry" mechanism while using pagination library android, in case of no internet or device went offline while loading items.

When I click the "retry" image I get error - "Attempt to invoke virtual method 'void com.myapp.myapp.repository.FeedDataSource.retryPagination()' on a null object reference"

FeedDataSource.java

public class FeedDataSource extends PageKeyedDataSource<Long, Feed> {
.....
//for retry
private LoadParams<Long> params;
private LoadCallback<Long, Feed> callback;
........
 @Override
public void loadAfter(@NonNull LoadParams<Long> params, @NonNull LoadCallback<Long, Feed> callback) {

    this.params = params;
    this.callback = callback;

    Log.e(TAG, "Loading rage" + params.key + " Count" + params.requestedLoadSize);
    networkState.postValue(NetworkState.LOADING);
    RestApi restApi = RetrofitApi.create();
    Call<FeedResponse> call = restApi.fetchFeed(params.key, params.requestedLoadSize, username);
    try
    {
        Response<FeedResponse> response = call.execute();
        if(response.isSuccessful()){
            FeedResponse feedResponse = response.body();
            if(feedResponse !=null){
                networkState.postValue(NetworkState.LOADED);
                List<Feed> responseItems = feedResponse.getFeeds();
                callback.onResult(responseItems, params.key + 1);
            }
      }
         ........
 }

  public void retryPagination()
{
    loadAfter(params, callback);
}

 }

FeedDataFactory.java

public class FeedDataFactory extends DataSource.Factory {

private MutableLiveData<FeedDataSource> mutableLiveData;
private FeedDataSource feedDataSource;
private AppController appController;

public FeedDataFactory(AppController appController){
    this.appController = appController;
    this.mutableLiveData = new MutableLiveData<FeedDataSource>();
}

@Override
public DataSource create() {
    feedDataSource = new FeedDataSource(appController);
    mutableLiveData.postValue(feedDataSource);
    return feedDataSource;
}

public MutableLiveData<FeedDataSource> getMutableLiveData(){
    return mutableLiveData;
   }
}

FeedViewModel.java

public class FeedViewModel extends ViewModel {

..............

public void retry() {
    FeedDataFactory feedDataFactory = new FeedDataFactory(appController);
    feedDataFactory.getMutableLiveData().getValue().retryPagination();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
  } 

FeedAdapter.java

public class FeedListAdapter extends PagedListAdapter<Feed, RecyclerView.ViewHolder> {
    ......
    private final Callback callback;

     public FeedListAdapter(@NonNull DiffUtil.ItemCallback<Feed> diffCallback, Callback callback, Context context) {
    super(Feed.DIFF_CALLBACK);
    this.context = context;
    this.callback = callback;
     }

    public void bindView(NetworkState networkState) {

            if (networkState != null && networkState.getStatus() == NetworkState.Status.FAILED) {
            binding.refresh.setVisibility(View.VISIBLE);
            binding.refresh.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    binding.refresh.setVisibility(View.GONE);
                    binding.progressBar.setVisibility(View.VISIBLE);
                    callback.onRetryClicked();
                }
            });
        } 
    }
     public interface Callback {
      void onRetryClicked();
      }
  }

HomeFragment.java

public class HomeFragment extends Fragment implements ClickHandler, FeedListAdapter.Callback {
  private FeedListAdapter feedListAdapter;
  private FeedViewModel feedViewModel;
   ..............
   @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        feedViewModel = new ViewModelProvider(this).get(FeedViewModel.class);
       feedViewModel.init(appController);

        feedListAdapter = new FeedListAdapter(Feed.DIFF_CALLBACK, this, getContext());

        recyclerView.setAdapter(feedListAdapter);

        feedViewModel.getArticleLiveData().observe(getViewLifecycleOwner(), pagedList -> {
        feedListAdapter.submitList(pagedList);
      });
      }
  }

Please help, what am I doing wrong!

Ibramazin
  • 958
  • 10
  • 30

1 Answers1

0

First of all, I want to thank you because your solution is a hint for me to implement the network retry thing, I really appreciate that.

Second, about the NullPointerException you're getting, it's because in your FeedViewModel.java, when the retry button is triggered, you create a whole new factory for datasource. It's not either necessary or right because the Factory wont create any new DataSource unless the previous one was invalidated. You should retrieve the DataSource through your current Factory.

Another problem I want to mention is that, if your request is failed, you don't call onResult(...) on the callback. Based on the documentation:

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)

Here is my implementation in DataSource when onFailure() in Retrofit is called:

@Override
        public void onFailure(Call<HotItemsResponse> call, Throwable t) {
            loadingState.postValue(Contants.LoadingState.SUB_LOAD_ERROR);
            //when the load is fail, dont call onResult() on the call back,
            //just ignore it, update the loading state for the UI to handle reload

            //callback.onResult(new ArrayList<ProductItem>(), currentPage);
        }
Dennis Nguyen
  • 278
  • 2
  • 9