Reputation: 906
Please help me understand what's happening here.
I have two fragments (A and B) in tabs reading data from different tables, via a CursorLoader and aContentProvider, in a Sqlite-database. With different URIs I can change which table the ContentProvider is quering.
I works as expected when switch between the tabs A and B, unless I switch to B, rotate and switches back to A the wrong cursor is returned. The cursor from fragment B is returned instead of a cursor for fragment A with makes the listView in fragment A to cause a crash. In some way the cursor seems to be reused on a rotation.
Why is this happening and how can I prevent that the wrong cursor is returned?
This is what I have in both fragment A and B. Tried to assing a loader id with no success.
public void onResume() {
super.onResume();
getLoaderManager().restartLoader(mLoaderId, null, this);
}
My ContentProvider looks like this:
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case ALL_NEWS:
queryBuilder.setTables(NewsDb.SQLITE_TABLE);
cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
break;
case SINGLE_PLACE:
queryBuilder.setTables(PlacesDb.SQLITE_TABLE);
String id = uri.getPathSegments().get(1);
queryBuilder.appendWhere(PlacesDb.KEY_ID + "=" + id);
cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
return cursor;
}
Upvotes: 1
Views: 548
Reputation: 25584
When using CursorLoader
, data changes are automatically observed, so you should definitely remove the restartLoader
call in your onResume()
. If implemented properly, you should only have to call initLoader
in onActivityCreated
of the Fragment
.
LoaderManager
IDs are only scoped to the Fragment
, so you should be using a static constant
ID. If the Loaders
are handled in the Fragments
, themselves, it's perfectly fine for every Fragment
to have the same Loader
ID (even if they're managed by the same Activity
).
So in each Fragment
:
private static final int LOADER_ID = 0;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// ...
getLoaderManager().initLoader(LOADER_ID, null, this);
}
Upvotes: 1