読者です 読者をやめる 読者になる 読者になる

CursorTreeAdapterのsetChildrenCursorで落ちるのを回避してみる

Android

(この対処が正しいのかはわかりません)

落ちるところ

ExpandableListView+CursorTreeAdapter+LoaderCallbacksで実装していて、

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        adapter.setChildrenCursor(ID, data);
    }

setChildrenCursorしようとするとNullPointerExceptionが出ることがある。

CursorTreeAdapter.javaの実装を見てみると、

    public void setChildrenCursor(int groupPosition, Cursor childrenCursor) {
        
        /*
         * Don't request a cursor from the subclass, instead we will be setting
         * the cursor ourselves.
         */
        MyCursorHelper childrenCursorHelper = getChildrenCursorHelper(groupPosition, false);

        /*
         * Don't release any cursor since we know exactly what data is changing
         * (this cursor, which is still valid).
         */
        childrenCursorHelper.changeCursor(childrenCursor, false); // <- ここで落ちる
    }
    synchronized MyCursorHelper getChildrenCursorHelper(int groupPosition, boolean requestCursor) {
        MyCursorHelper cursorHelper = mChildrenCursorHelpers.get(groupPosition);
        
        if (cursorHelper == null) {
            if (mGroupCursorHelper.moveTo(groupPosition) == null) return null; // <- nullを返すことがある
            
            final Cursor cursor = getChildrenCursor(mGroupCursorHelper.getCursor());
            cursorHelper = new MyCursorHelper(cursor);
            mChildrenCursorHelpers.put(groupPosition, cursorHelper);
        }
        
        return cursorHelper;
    }

childrenCursorHelpernullになることがあり、changeCursor()を呼び出すのでNullPointerExceptionが出る。

・・nullチェックされていなくて涙目です。

が、nullになる状況を作り出している私のコードに問題があるのかもしれません。
(まだわかってない)

対処

以下のような応急処置をしました。

先にGroupCursorの生存を確認してから、setChildrenCursorするようにした。

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        Cursor groupCursor = adapter.getGroup(ID);

        if (groupCursor == null) {
            return;
        }

        adapter.setChildrenCursor(ID, data);
    }

getGroupの中身は・・

    public Cursor getGroup(int groupPosition) {
        // Return the group Cursor pointing to the given group
        return mGroupCursorHelper.moveTo(groupPosition);
    }

先ほどの「nullチェックされてなくて涙目」な部分を、
「自分で事前にチェックしてみた」ということになった。

NullPointerExceptionをcatchしてやりすごすよりは、良いかな??