如何确保在显示来自 API 的无限数据时不会出现 NullPointerException。



我正在从api获取数据并将它们显示在recyclerview中。

我正在使用无限滚动在滚动时加载更多数据。

如果我顺利滚动,它可以正常工作,但如果我快速滚动,我会得到 NullPointerException,因为即使在我检查适配器类中的模型数据是否为空之后,也没有按时获取数据。

如何避免这种情况?

请在下面找到代码:

 @NonNull
private InfiniteScrollListener createInfiniteScrollListener() {
    return new InfiniteScrollListener(10, linearLayoutManager) {
        @Override public void onScrolledToEnd(final int firstVisibleItemPosition) {
                offset += 10;
                final List<Purchase2> itemsLocal = loadMore(offset);
                refreshView(recyclerView, new PurchaseMainTestAdapter(itemsLocal, R.layout.list_orders_layout, getApplicationContext(), emptyView), firstVisibleItemPosition);
        }
    };
}
private List<Purchase2> loadMore(int index){
    progressBar.setVisibility(View.VISIBLE);
    //add loading progress view
    purchases.add(new Purchase2());
    adapter.notifyItemInserted(purchases.size()-1);
    OneViewApi apiService =
            ApiClient.getClient().create(OneViewApi.class);
    Call<Orders> call;
    call = apiService.getPurchaseData(auth_token,index,10);
    Log.d("Called url is:", call.request().url().toString());
    call.enqueue(new Callback<Orders>() {
        @Override
        public void onResponse(Call<Orders> call, Response<Orders> response) {
            if(response.isSuccessful()){
                //remove loading view
                purchases.remove(purchases.size()-1);
                List<Purchase2> result = response.body().getPurchases();
                if(result.size()>0){
                    //add loaded data
                    purchases.addAll(result);
                }else{//result size 0 means there is no more data available at server
                    adapter.setMoreDataAvailable(false);
                    Toast.makeText(getApplicationContext(),"No More Data Available",Toast.LENGTH_LONG).show();
                }
                progressBar.setVisibility(View.GONE);
                //should call the custom method adapter.notifyDataChanged here to get the correct loading status
            }else{
                Log.e("Item list"," Load More Response Error "+String.valueOf(response.code()));
            }
        }
        @Override
        public void onFailure(Call<Orders> call, Throwable t) {
            Log.e("Item list"," Load More Response Error "+t.getMessage());
        }
    });
    return purchases;
}

首次使用try{} catch{}然后通过断点跟踪代码,以便在发生异常时进行精细

但我想这里会发生例外:purchases.remove(purchases.size()-1);您的列表为空并且您正在尝试删除项目。(第一次)或关于添加和删除项目。

但是对于检测显示负载是否更多,您可以将null添加到purchases list然后在适配器中处理它 - 它太好了

修复

了此空指针异常:

1.) 在内部添加了适配器代码

try{}

catch{} block

2.) 已设置标志,以便在滚动时无法再次调用服务,直到执行最后一个服务为止

if(!isLoading) {
                isLoading = true;
                    final List<Purchase2> itemsLocal = loadMorePurchaseData(offset, null, null, null);
                    refreshView(recyclerView, new PurchaseMainAdapter(itemsLocal, R.layout.list_orders_layout, getApplicationContext(), emptyView), firstVisibleItemPosition);}

并在网络调用中设置适当的标志:

     public void onResponse(Call<Orders> call, Response<Orders> response) {
            if(response.isSuccessful()){

                List<Purchase2> result = response.body().getPurchases();
                if(result.size()>0){
                    //add loaded data
                    purchases.addAll(result);
                }else{//result size 0 means there is no more data available at server
                    purchase_adapter.setMoreDataAvailable(false);
                    //telling adapter to stop calling load more as no more server data available
                    Toast.makeText(getApplicationContext(),"No More Data Available",Toast.LENGTH_LONG).show();
                }
                progressBar.setVisibility(View.GONE);
                isLoading = false;
                //should call the custom method adapter.notifyDataChanged here to get the correct loading status
            }else{
                Log.e("Item list"," Load More Response Error "+String.valueOf(response.code()));
            }

谢谢大家的提示。

最新更新