Фильтр списка Android не работает с NPE - PullRequest
1 голос
/ 10 февраля 2011

В моем приложении у меня есть ListView, адаптер для него и фильтр для адаптера. Это фильтр:

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

Правильно ли я понимаю, что publishResults ВСЕГДА вызывается после выполнения его работы по фильтрации? Даже эта работа очень тяжелая и долгая? У меня есть ситуация, когда publishResults запускается внезапно, и, конечно, поле «FilterContacts» моего адаптера устанавливается в NULL.

Я попытался упростить работу по выполнению фильтрации (удалив цикл и напишите что-то вроде «FilterContacts.add (new Contact ())»), и тогда все работает нормально.

И, наконец, этот код работал нормально несколько дней ... Я запутался. Кто-нибудь может объяснить, что происходит?) Заранее спасибо!

1 Ответ

0 голосов
/ 11 февраля 2011

Хорошо, ребята! Я понял! executeFiltering (...) запускается в рабочем потоке и когда

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

завершается с ошибкой NullPointerException для c.getName (). ToLowerCase () (поскольку getName () возвращает значение null), его поток тоже завершается с ошибкой, но кажется, что sdk где-то перехватывает это исключение и поток просто умирает.

Кроме того, publishResults может быть вызван в любое время потоком пользовательского интерфейса, поэтому требуется проверка на нуль:

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