简体   繁体   中英

Android ListView filter fail with NPE

In my app i have ListView, Adapter for it, and Filter for Adapter. This is filter:

private Filter nameFilter = new Filter() {

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        List<Contact> resultContacts = (List<Contact>) results.values;
        filteredContacts = resultContacts;
        notifyDataSetChanged();
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<Contact> filteredContacts = new ArrayList<Contact>();
        for(Contact c : rawContacts){
            if(!c.getName().toLowerCase().contains(constraint.toString().toLowerCase())){
                continue;
            }
            filteredContacts.add(c);
        }

        FilterResults filterResults = new FilterResults();
        filterResults.values = filteredContacts;
        return filterResults;
    }
};

Do I understand correctly that publishResults ALWAYS invoked after performFiltering done his job? Even this job is veeeery hard and long? I have a situation when publishResults runs suddenly and of course field "filteredContacts" of my Adapter sets to NULL.

I tried to make easier the job of performFiltering (by removing the cycle and write something like "filteredContacts.add(new Contact())") and then all works fine.

And finally this code worked fine few days... I confused. Can anybody explain what is going on?) Thanks in advance!

Ok guys! I got it! performFiltering(...) runs in worker thread and when

if(!c.getName().toLowerCase().contains(constraint.toString().toLowerCase())){
            continue;
}

fails with NullPointerException on c.getName().toLowerCase() (because getName() returns null), it's thread fails too, but it seems that sdk somewhere cathes this exception and thread just die.

Also, publishResults can be invoked at any time by UI thread so null checking required:

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    if(results.values != null) {
       List<Contact> resultContacts = (List<Contact>) results.values;
       filteredContacts = resultContacts;
       notifyDataSetChanged();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM