我在 s 中有一系列ListView
对象,这些对象由 a从活动中获取 aFragment
填充。据我了解,所有数据库和关闭操作都完全由和处理,因此我在任何代码中都没有调用任何内容。CursorAdapter
Cursor
LoaderManager
Cursor
LoaderManager
ContentProvider
.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
告诉我何时或正在被调用,似乎在给定适配器的第一次发生这种情况,而对于另一个适配器则发生了很多s。当用户在应用程序中导航了很多之后,也会发生这种情况。getView(...)
getItem(...)
getItemId(...)
getView(...)
getView(...)
这让我想知道Cursor
适配器的 是否保留在 中CursorAdapter
,但被ContentProvider
或错误关闭Loader
。这可能吗?我应该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);
}
我已经阅读了这个问题,但不幸的是它没有得到我的问题的答案,因为它只是建议使用 a ContentProvider
,我就是这样。
IllegalStateException:尝试重新打开已经关闭的对象。SimpleCursorAdapter 问题
刚刚曝光的重要新信息
我在项目的其他地方发现了一些其他代码,它们没有使用Loader
s 并且没有正确管理它Cursor
的 s。我刚刚切换了这段代码以使用与上面相同的模式;但是,如果这可以解决问题,则表明Cursor
项目的某个部分中未受管理的人可能会在其他地方杀死受适当管理的人。
停在附近。
新信息的结果
那并没有解决它。
新理念
@Override
onDestroyView() {
getActivity().getLoaderManager().destroyLoader(mFragmentId);
//any other destroy-time code
super.onDestroyView()
}
即可能是的,我应该对CursorAdapter
(或者更确切地说CursorLoader
符合生命周期事件)进行内务处理。
新理念的成果
没有。
以前的想法
一旦我添加了一个小调整,结果就可以工作了!但是它太复杂了,我可能应该重写整个问题。