Сбой в ListView.removeFooterView(просмотр)

Я получаю отчеты о сбоях

 android.widget.ListView  lv;  lv.removeFooterView(v)

Ошибка - это исключение из null-указателя. Я проверяю, что listView не имеет значения null. Что вызывает это? Нужно ли убедиться, что вид, который нужно удалить, не равен нулю? Является ли это достаточным или сначала нужно проверить, действительно ли был добавлен вид нижнего колонтитула?

java.lang.NullPointerException
at android.widget.ListView.removeFooterView(ListView.java:374)

Мне кажется, что этот метод должен быть достаточно устойчивым, чтобы не рухнуть! Почему он не просто возвращает false, если он не может удалить представление?

PS. Я хотел бы знать, видел ли кто-нибудь еще это?

Ответ 1

К сожалению, вы не упоминаете, какую версию Android вызывают отчеты об ошибках. Однако, глядя на исходный код, Android 2.1-update1 кажется хорошим кандидатом.

Я просто скопирую весь метод, чтобы все было ясно:

public boolean removeFooterView(View v) {
    if (mFooterViewInfos.size() > 0) {
        boolean result = false;
        if (((HeaderViewListAdapter) mAdapter).removeFooter(v)) { // <- line 274
            mDataSetObserver.onChanged();
            result = true;
        }
        removeFixedViewInfo(v, mFooterViewInfos);
        return result;
    }
    return false;
}

Теперь сравните выше метод removeFooterView(...) с реализацией более новой платформы:

public boolean removeFooterView(View v) {
    if (mFooterViewInfos.size() > 0) {
        boolean result = false;
        if (mAdapter != null && ((HeaderViewListAdapter) mAdapter).removeFooter(v)) {
            if (mDataSetObserver != null) {
                mDataSetObserver.onChanged();
            }
            result = true;
        }
        removeFixedViewInfo(v, mFooterViewInfos);
        return result;
    }
    return false;
}

Как вы можете видеть, "добавлено в несколько дополнительных проверок для определенных членов, не являющихся null. Это означало бы, что первый метод действительно завершится неудачно в строке 274, если mAdapter == null, тогда как это не приведет к сбою в более новой реализации.

Чтобы обойти это, все, что вам, вероятно, нужно сделать, это добавить что-то вроде lv.getAdapter() != null, прежде чем пытаться удалить нижний колонтитул.

Ответ 2

ЕСЛИ вы проверяете документацию, вы заметите, что это действительно так:

http://developer.android.com/reference/android/widget/ListView.html)

Возвращает

true, если представление было удалено, false, если представление не было представлением нижнего колонтитула

Итак, вы должны добавить нулевую проверку как для представления, так и для listView или если это исключительное состояние (происходит очень редко, а затем завертывает его в блок исключений).