在分页库中实现重试android错误-空指针异常 [英] Implementing Retry in pagination library android error - Null pointer Exception

查看:46
本文介绍了在分页库中实现重试android错误-空指针异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施重试"使用分页库android时的机制,以防在加载项目时没有互联网或设备离线.

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

当我点击重试"时图像我收到错误 - 尝试在空对象引用上调用虚方法 'void com.myapp.myapp.repository.FeedDataSource.retryPagination()'"

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!

推荐答案

首先,我要感谢你,因为你的解决方案是我实现网络重试的提示,我真的很感激.

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.

第二,关于你得到的 NullPointerException,这是因为在你的 FeedViewModel.java 中,当重试按钮被触发时,你为数据源创建了一个全新的工厂.这既不必要也不正确,因为工厂不会创建任何新的数据源,除非前一个数据源无效.您应该通过您当前的工厂检索数据源.

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.

我想提到的另一个问题是,如果您的请求失败,您不会在回调中调用 onResult(...).基于文档:

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:

一个回调只能被调用一次,如果再次调用就会抛出.它对于采用回调的 DataSource 加载方法始终有效隐藏回调并稍后调用.这使数据源能够完全异步,并处理临时的、可恢复的错误状态(例如可以重试的网络错误)

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)

这是调用 Retrofit 中的 onFailure() 时我在 DataSource 中的实现:

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);
        }

这篇关于在分页库中实现重试android错误-空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆