android - Fragments、ContentProviders 和方向变化的游标

标签 android android-contentprovider android-orientation android-cursorloader

请帮助我了解这里发生了什么。

我在选项卡中有两个 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 调用。如果实现得当,您只需在 FragmentonActivityCreated 中调用 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/

相关文章:

Android - 长按 RecyclerView 项目和 ContextMenu

android - 在后退按钮上 "IllegalStateException: Can not perform this action after onSaveInstanceState"

android - 如何检查该词是否已在用户词典中可用?

android - 即使关闭 autoRotation 也能获取 android 设备方向

Android:方向更改后自定义动画丢失

java - RxJava 背压(快速生产者慢消费者)

Android:在线性布局中创建两列

Android 保存图片到文件系统

android - 以 WebService 为源的 ContentProvider

android - 处理 android 中的运行时方向变化