请帮助我了解这里发生了什么。
我在选项卡中有两个 fragment (A 和 B),通过 Sqlite 数据库中的 CursorLoader 和 ContentProvider 从不同的表读取数据。使用不同的 URI,我可以更改 ContentProvider 正在查询的表。
在选项卡 A 和 B 之间切换时,我按预期工作,除非我切换到 B,旋转并切换回 A,否则会返回错误的光标。返回 fragment B 的游标而不是 fragment A 的游标,这使得 fragment A 中的 listView 导致崩溃。在某种程度上,光标似乎在旋转时被重复使用。
为什么会发生这种情况,如何防止返回错误的光标?
这是我在 fragment A 和 fragment B 中所拥有的。尝试分配加载程序 ID 但没有成功。
public void onResume() {
super.onResume();
getLoaderManager().restartLoader(mLoaderId, null, this);
}
我的 ContentProvider 看起来像这样:
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;
}
最佳答案
当使用 CursorLoader
时,数据变化会被自动观察到,因此您绝对应该删除 onResume()
中的 restartLoader
调用。如果实现得当,您只需在 Fragment
的 onActivityCreated
中调用 initLoader
。
LoaderManager
ID 仅限于 Fragment
,因此您应该使用 static constant
ID。如果 Loaders
在 Fragments
中处理,那么每个 Fragment
都具有相同的 Loader
ID(即使它们由相同的 Activity
管理)。
所以在每个 fragment
中:
private static final int LOADER_ID = 0;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// ...
getLoaderManager().initLoader(LOADER_ID, null, this);
}
关于android - Fragments、ContentProviders 和方向变化的游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20180929/