gpt4 book ai didi

android - 来自 ContentProvider 的 SimpleCursorAdapter 中的 IllegalStateException "attempt to re-open an already-closed object"

转载 作者:太空宇宙 更新时间:2023-11-03 11:17:01 26 4
gpt4 key购买 nike

我在 Fragment 中有一系列 ListView 对象,这些对象由 CursorAdapter 填充,它获得一个 Cursor 来自 Activity 的 LoaderManager。据我了解,所有数据库和 Cursor 关闭操作都完全由 LoaderManagerContentProvider 处理,因此在任何时候都不会代码我在任何事情上调用.close()

然而,有时我会得到这个异常:

02-19 11:07:12.308 E/AndroidRuntime(18777): java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT * FROM privileges WHERE uuid!=?) 
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:33)
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:82)
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:164)
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:147)
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:178)
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:162)
02-19 11:07:12.308 E/AndroidRuntime(18777): at android.widget.CursorAdapter.getView(CursorAdapter.java:241)

我将一些日志代码放入我的 CursorAdapter 中,告诉我什么时候 getView(...)getItem(...)getItemId(...) 正在被调用,这似乎发生在给定适配器的第一个 getView(...) 之后很多 getView(...)s 用于另一个适配器。它也会在用户多次浏览应用程序后发生。

这让我想知道适配器的 Cursor 是否保留在 CursorAdapter 中,但被 ContentProvider 错误关闭或加载器。这可能吗?我是否应该根据应用程序/Activity/fragment 生命周期事件对 CursorAdapter 进行任何管理?

ContentProvider查询方法:

class MyContentProvider extends ContentProvider {
//...

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor query = db.query(getTableName(uri), projection, selection, selectionArgs, null, null, sortOrder);
query.setNotificationUri(getContext().getContentResolver(), uri);
return query;
}

//...
}

典型的LoaderCallbacks:

LoaderCallbacks<Cursor> mCallbacks = new LoaderCallbacks<Cursor>() {

@Override
public void onLoaderReset(Loader<Cursor> loader) {
mArticleAdapter.swapCursor(null);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if(cursor.isClosed()) {
Log.d(TAG, "CURSOR RETURNED CLOSED");
Activity activity = getActivity();
if(activity!=null) {
activity.getLoaderManager().restartLoader(mFragmentId, null, mCallbacks);
}
return;
}
mArticleAdapter.swapCursor(cursor);
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
triggerArticleFeed();
CursorLoader cursorLoader = null;

if(id == mFragmentId) {
cursorLoader = new CursorLoader(getActivity(),
MyContentProvider.ARTICLES_URI,
null,
ArticlesContentHelper.ARTICLES_WHERE,
ArticlesContentHelper.ARTICLES_WHEREARGS,
null);
}
return(cursorLoader);
}
};

CursorAdapter 构造函数:

public ArticlesCursorAdapter(Context context, Cursor c) {
super(context, c, 0);
mImageloader = new ImageLoader(context);
}

我已经阅读了这个问题,但不幸的是它没有得到我的问题的答案,因为它只是建议使用 ContentProvider,我就是。

IllegalStateException: attempt to re-open an already-closed object. SimpleCursorAdapter problems

刚刚曝光的重要新信息

我在项目的其他地方发现了一些其他代码,这些代码没有使用 Loader 并且没有正确管理其 Cursor。我刚刚将这段代码切换为使用与上面相同的模式;但是,如果这解决了问题,则表明项目的一部分中的非托管 Cursor 可能会杀死其他地方正确管理的游标。

留下来。

新信息的结果

这并没有解决问题。

新想法

@Override
onDestroyView() {
getActivity().getLoaderManager().destroyLoader(mFragmentId);
//any other destroy-time code
super.onDestroyView()
}

即可能是的,我应该CursorAdapter(或者更确切地说是CursorLoader)上根据生命周期事件进行管理。

新想法的成果

没有。

先前的想法

一旦我添加了一个小调整,结果就可以工作了!然而,它太复杂了,我可能应该重写整个问题。

最佳答案

您更新数据集了吗?可能是由于通知内容解析器发生了变化,光标已被重新加载:

getContentResolver().notifyChange(URI, null);

如果您设置了一个通知 URI,这将触发您当前的游标关闭并由游标加载器返回一个新的游标。如果您已经注册了一个 onLoadCompleteListener,那么您可以获取新的光标:

mCursorLoader.registerListener(0, new OnLoadCompleteListener<Cursor>() {
@Override
public void onLoadComplete(Loader<Cursor> loader, Cursor cursor) {
// Set your listview's CursorAdapter
}
});

关于android - 来自 ContentProvider 的 SimpleCursorAdapter 中的 IllegalStateException "attempt to re-open an already-closed object",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14956608/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com