Loader
によって編集されているデータベースを取得するために s を使用しているアプリケーションがありますIntentService
。正常に動作している実装Loader
を通じてからデータを受け取ります。LoaderCallbacks
ContentResolver#notifyChange(Uri, ContentObserver)
リロードのトリガーにも使用しています。ただし、これはCursor#setNotificationUri(Uri)
事前に電話した場合にのみ機能します。
どのドキュメントにも後者の方法への参照が見つかりません。実際、これがクラッシュを引き起こしている可能性があるようです: も参照してください。
ContentProvider の SimpleCursorAdapter で IllegalStateException "既に閉じられているオブジェクトを再度開こうとしています"
ただし、この呼び出しがないと、通知後Cursor
でLoaderCallbacks#onLoadFinished(Loader<Cursor>, Cursor)
はなく、初期ロード後にのみヒットします。またOnLoadCompleteListener
、まったく同じことを行う必要がありますか?
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);
}
};