0

このバグを再現することはできませんでしたが、この問題が発生したことでクラッシュ レポートが細流になっています。リストアダプターにヌルチェックを追加すると修正されると思いましたが、まだ発生しています。私は何が欠けていますか?

完全なスタックトレース: http://pastebin.com/Q6GwDU7Q

    public void onLoaderReset(Loader<Cursor> loader) {
    final int id = loader.getId();
    switch (id) {
    case LOADER_ID1:
        if (mAdapter != null)
            mAdapter.changeCursor(null); //Line 512 where stacktrace references
        break;
    case LOADER_ID2:
        //Other code here
        break;
    default:
        throw new InvalidParameterException("id=" + id);
    }
}

mAdapter は onActivityCreated で初期化されますが、これを入力しているときに解放しないことに気付きました。おそらく onDetach で実行する必要がありますか? mAdapter は、ListFragment によって設定された ListView にアタッチされます。そして、アダプターのカーソルを null に設定して、リストをクリアします。そうです、私は何を見落としていますか?

4

1 に答える 1

0

Android ソースを検索した後、GreyBearedGeek が述べたように、ローダーが Cursor 破壊を処理できるようにする必要があることがわかりました。

CursorLoader でわかるように、新しいカーソルを渡すと、古いカーソルを閉じる処理が行われます。

    /* Runs on the UI thread */
@Override
public void deliverResult(Cursor cursor) {
    if (isReset()) {
        // An async query came in while the loader is stopped
        if (cursor != null) {
            cursor.close();
        }
        return;
    }
    Cursor oldCursor = mCursor;
    mCursor = cursor;

    if (isStarted()) {
        super.deliverResult(cursor);
    }

    if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
        oldCursor.close();
    }
}

リセット時にカーソルを閉じるだけでなく。

    @Override
protected void onReset() {
    super.onReset();

    // Ensure the loader is stopped
    onStopLoading();

    if (mCursor != null && !mCursor.isClosed()) {
        mCursor.close();
    }
    mCursor = null;
}

したがって、これが上記のスタックトレースで NPE を引き起こす方法をまだ確認していませんが、CursorLoaders の処理を​​妨げないように、将来は swapCursor を使用します。

于 2013-06-05T02:32:40.180 に答える