アクティビティのからを取得するによって入力されている一連のListView
オブジェクトがFragment
sにあります。私が理解しているように、すべてのデータベースとクローズアクションは、とによって完全に処理されるため、コードのどの時点でも、私は何も呼び出していません。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
いつ呼び出されるかgetView(...)
、getItem(...)
またはgetItemId(...)
呼び出されているかを示すログコードを自分に挿入しました。これは、別のアダプターgetView(...)
で多くの秒が発生した後、特定のアダプターで最初に発生しているように見えます。getView(...)
また、ユーザーがアプリ内を何度も移動した後にも発生します。
Cursor
これにより、アダプタのforがに保持されているのに、または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);
}
私はこの質問を読みましたが、残念ながら、私が使用していることを示唆しているだけなので、私の問題に対する答えは得られていませんContentProvider
。
IllegalStateException:すでに閉じられているオブジェクトを再度開こうとします。SimpleCursorAdapterの問題
明らかになったばかりの重要な新しい情報
プロジェクトの他の場所で、sを使用しておらず、 sを適切Loader
に管理していない他のコードを発見しました。Cursor
上記と同じパターンを使用するようにこのコードを切り替えました。ただし、これで問題が解決した場合Cursor
は、プロジェクトの一部で管理されていない場合、他の場所で適切に管理されているプロジェクトを強制終了する可能性があります。
くっつき回る。
新しい情報の結果
それはそれを修正しませんでした。
新しい考え
@Override
onDestroyView() {
getActivity().getLoaderManager().destroyLoader(mFragmentId);
//any other destroy-time code
super.onDestroyView()
}
つまり、おそらくそうです、私は(またはライフサイクルイベントに沿って)ハウスキーピングを行う必要があります。CursorAdapter
CursorLoader
新しいアイデアの成果
いいえ。
前のアイデア
ちょっとした調整を加えると、動作することがわかりました。ただし、非常に複雑なので、おそらく質問全体を書き直す必要があります。