搜索适配器 - 空对象引用上的“java.lang.Object[] java.util.Collection.toArray()”

Posted

技术标签:

【中文标题】搜索适配器 - 空对象引用上的“java.lang.Object[] java.util.Collection.toArray()”【英文标题】:Search adapter - 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference 【发布时间】:2020-12-26 11:48:50 【问题描述】:

我做了一个 SearchAdapter 来实时过滤项目,但是有 NPE,我不知道该怎么做...... 它有时会起作用,但会产生 NPE 并关闭应用程序。

这些是我为制作此适配器而遵循的链接 - https://codinginflow.com/tutorials/android/searchview-recyclerview https://www.youtube.com/watch?v=ujKDN_ZtGHQ

这里是适配器代码和错误日志。

public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchViewHolder> implements Filterable 

private ArrayList<SearchItem> searchList;
private ArrayList<SearchItem> searchListFull;
private SelectedPlace selectedPlace;

class SearchViewHolder extends RecyclerView.ViewHolder 
    ImageView imageView;
    TextView searchPlace;
    TextView searchFolder;
    SearchViewHolder(View itemView) 
        super(itemView);
        imageView = itemView.findViewById(R.id.image_view);
        searchPlace = itemView.findViewById(R.id.text_view1);
        searchFolder = itemView.findViewById(R.id.text_view2);

        itemView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                selectedPlace.selectedPlace(searchList.get(getAdapterPosition()));
            
        );
    

SearchAdapter(ArrayList<SearchItem> searchList, SelectedPlace selectedPlace) 
    this.searchList = searchList;
    searchListFull = new ArrayList<>(searchList);
    this.selectedPlace = selectedPlace;

@NonNull
@Override
public SearchAdapter.SearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_item,
            parent, false);
    return new SearchViewHolder(v);

@Override
public void onBindViewHolder(@NonNull SearchAdapter.SearchViewHolder holder, int position) 
    SearchItem currentItem = searchList.get(position);
    if(currentItem.getAttempts() < 3)
        holder.imageView.setImageResource(R.drawable.ps_place_under);
     else if(currentItem.getStarred() == 0)
        holder.imageView.setImageResource(R.drawable.ps_place_over);
     else 
        holder.imageView.setImageResource(R.drawable.ic_star_chk_24dp);
    
    holder.searchPlace.setText(currentItem.getPlace());
    holder.searchFolder.setText(currentItem.getFolder());

@Override
public int getItemCount() 
    return searchList.size();


public interface SelectedPlace
    void selectedPlace(SearchItem searchItem);


@Override
public Filter getFilter() 
    return searchFilter;

private Filter searchFilter = new Filter() 
    @Override
    protected FilterResults performFiltering(CharSequence constraint) 
        List<SearchItem> filteredList = new ArrayList<>();
        if (constraint == null || constraint.length() == 0) 
            filteredList.addAll(searchListFull);
         else 
            String filterPattern = constraint.toString().toLowerCase().trim();
            for (SearchItem item : searchListFull) 
                if (item.getFolder().toLowerCase().contains(filterPattern)) 
                    filteredList.add(item);
                
                else if (item.getPlace().toLowerCase().contains(filterPattern))
                    filteredList.add(item);
                
            
        
        FilterResults results = new FilterResults();
        results.values = filteredList;
        return results;
    
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) 
        searchList.clear();
        searchList.addAll((List) results.values);
        notifyDataSetChanged();
    
;


错误日志 --------------------------------------------- -------------------------------------------

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object[] 

java.util.Collection.toArray()' on a null object reference      
at java.util.ArrayList.addAll(ArrayList.java:588)
        at com.ljh.GetOut.SearchAdapter$1.publishResults(SearchAdapter.java:104)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:284)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

【问题讨论】:

performFiltering() 中可能早先抛出了另一个异常。在您的日志中进一步查找另一个堆栈跟踪。 @Mike.M.现在我检查它在 performFiltering() 处引发异常,NPE at 'java.lang.String java.lang.String.toLowerCase()' 是的,我就是这么想的。看起来 item.getFolder() 和/或 item.getPlace() 至少为您的一项项目返回 null。如果允许,那么您需要先检查 null,然后再对它们执行 toLowerCase().contains()。否则,如果这些不应该为空,您需要查看生成列表的位置,以了解您最终如何获得具有空值的项目。 @Mike.M 感谢如果没有您的帮助,您将无法找到真正的原因。你是一个救生员! 【参考方案1】:

您的results.values 可能为空,或者它可能包含其他对象而不是SearchItem。您应该更加谨慎以防止此类错误。

试试这样的:

@Override
protected void publishResults(CharSequence constraint, FilterResults results) 

    searchList.clear();
    if(results.values instanceof List)
        for(Object item : (List<Object>)results.values)
            if(item instanceof SearchItem)
                searchList.add((SearchItem) item);
            
        
    
    notifyDataSetChanged();

【讨论】:

以上是关于搜索适配器 - 空对象引用上的“java.lang.Object[] java.util.Collection.toArray()”的主要内容,如果未能解决你的问题,请参考以下文章

空对象引用上的 BraintreeHttpClient.setBaseUrl(java.lang.String)

适配器抛出 java.lang.NullPointerException

java.lang.NullPointerException:尝试在 OnPostExecute() 上的空对象引用错误上调用接口方法 - AsyncTask

空对象引用上的 Android Studio jTDS java.lang.NullPointerException java.sql.Statement java.sql.Connection.cr

尝试在 recyclerview kotlin 上的空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)

java.lang.Class java.lang.Object.getClass()' 在空对象引用上