Android 基础数据更改时未刷新游标加载程序
我有一个内容提供者、一个内容解析器和一个游标加载器。加载程序用于间接填充listview(即不是一个简单的游标适配器,而是一个数组适配器,因为我需要使用游标的结果来收集其他数据) 当我更改基础数据时,listview不会重新填充,因为不会调用Android 基础数据更改时未刷新游标加载程序,android,android-cursorloader,Android,Android Cursorloader,我有一个内容提供者、一个内容解析器和一个游标加载器。加载程序用于间接填充listview(即不是一个简单的游标适配器,而是一个数组适配器,因为我需要使用游标的结果来收集其他数据) 当我更改基础数据时,listview不会重新填充,因为不会调用onLoadFinished(Loader,Cursor)回调 正如我在写这篇文章时所建议的,在这个问题上有很多问题。 如 所有的问题都指出了两件事: 在contentproviderquery()方法中,您需要告诉光标关于通知的信息 c.setNot
onLoadFinished(Loader,Cursor)
回调
正如我在写这篇文章时所建议的,在这个问题上有很多问题。
如
所有的问题都指出了两件事:
- 在contentproviderquery()方法中,您需要告诉光标关于通知的信息
c.setNotificationUri(getContext().getContentResolver(),uri)代码>
- 在内容提供商插入/更新/删除方法中,您需要通知URI:
getContext().getContentResolver().notifyChange(uri,null)代码>
我在做那些事
我也不会关闭我得到的任何游标
请注意,我的内容提供商位于一个单独的应用程序中(将其视为一个内容提供商应用程序——无启动器主活动)。一个com.example.provider APK,并且com.example.app正在通过content://com.example.provider/table 内容解析器(dbhelper)位于活动链接的库项目(com.example.appdb)中。(这样,多个项目可以通过链接使用dbhelper,所有内容提供商都通过单个APK安装)
我已经在加载程序管理器中打开了调试,可以看到在数据更改后强制刷新的位置(即加载程序被重新启动,而之前的加载程序被标记为非活动),但是没有任何东西表明任何事情是自动发生的,而是响应我的强制刷新
知道为什么我的加载器没有被刷新吗
--编辑--
加载程序将创建:
Log.d(TAG, "onCreateLoader ID: " + loaderID);
// typically a switch on the loader ID, and then
return dbHelper.getfoo()
其中getfoo()通过以下方式返回光标加载器:
返回新的游标装入器(上下文、FOO_URI、FOO_字段、FOO_查询、FOO_argArray、FOO_排序)代码>
Loader Finish接收光标并填充一个表(并进行一些处理)——没有什么特别之处
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
Log.d(TAG, "onLoadFinished id: " + loader.getId());
// switch on loader ID ..
FillTable(cursor, (FooAdapter) foo_info.listview.getAdapter();
然后插入/更新类似于:
public Uri insert(Uri uri, ContentValues initialValues) {
ContentValues values;
if (initialValues != null) {
values = new ContentValues(initialValues);
} else {
values = new ContentValues();
}
String tableName;
Uri contentUri;
switch (sUriMatcher.match(uri)) {
case FOO:
tableName = FOOTABLE;
contentUri = FOO_URI;
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
SQLiteDatabase db = dbHelper.getWritableDatabase();
long rowId = db.insert(tableName, null, values);
if (rowId > 0) {
Uri objUri = ContentUris.withAppendedId(contentUri, rowId);
getContext().getContentResolver().notifyChange(objUri, null);
return objUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
我发现您没有在onLoadFinished和onLoaderReset中调用swapCursor或changeCursor。您需要这样做,适配器才能访问加载到新游标中的数据
在onLoadFinished中,调用如下内容:
mAdapter.swapCursor(cursor)
在onLoaderReset中,调用此选项以删除对旧光标的引用:
mAdapter.swapCursor(null)
其中mAdapter是listView的适配器
更多信息:因此,对于查找此信息并遇到此问题的任何人:
确保注册光标的URI与通知光标的URI相同
在我的例子中,我使用的URI与修改基础表的其他代码中使用的URI不同。没有一个简单的修复方法可以让通知生效,所以我一直在重置OnResume()中的加载程序作为解决方案。这不是对这个特定问题的直接回答,但可能会帮助其他类似情况的人。在我的例子中,我有一个连接,即使我在投影和查询中使用了完整的tablename.columnname。它最终还是使用了错误的ID值。因此,请务必检查ContentProvider或SQL语法。发布一些与游标加载程序相关的代码可能会有所帮助。主要是onCreateLoader、onLoaderReset和onLoadFinished方法。我假设您的ContentProvider在您刷新时到达notifyChange调用。很抱歉,风暴/断电等让我离开了一段时间。我可能选择了代码中的第一个示例,它是一个阵列适配器,因为我们需要查找光标中或光标所在的数据库中都没有的其他信息(即它位于另一个数据库中,因此我不能在查询中使用联接)。还有其他几个simplecursoradapter(或从简单游标派生的),它们对返回的数据执行swapCursor()
(也不自动刷新)。您是否使用SimpleCursorAdapter然后查找其他信息?在我看来,您最好使用在适配器类中执行添加查找的自定义适配器。我必须查看调用swapCursor()
的其他适配器,但不要刷新,因为它们可能有其他问题。
mAdapter.swapCursor(cursor)
mAdapter.swapCursor(null)