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

因此,我将在未来使用 swapCursor 以不干扰 CursorLoaders 处理,即使我还没有看到这如何导致我在上面的堆栈跟踪中出现 NPE。

于 2013-06-05T02:32:40.180 回答