【发布时间】:2012-04-05 18:37:38
【问题描述】:
我有一个自定义的ContentProvider,它管理对 SQLite 数据库的访问。要将数据库表的内容加载到 ListFragment 中,我将 LoaderManager 与 CursorLoader 和 CursorAdapter 一起使用:
public class MyListFragment extends ListFragment implements LoaderCallbacks<Cursor> {
// ...
CursorAdapter mAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new CursorAdapter(getActivity(), null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(), CONTENT_URI, PROJECTION, null, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
mAdapter.swapCursor(c);
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
SQLite 数据库由后台任务更新,该任务从 Web 服务中获取一些项目,并通过 ContentProvider 批处理操作 (ContentResolver#applyBatch()) 将这些项目插入数据库。
即使这是一个批处理操作,ContentProvider#insert() 也会为插入数据库的每一行调用,并且在当前实现中,ContentProvider 会为每个插入命令调用 setNotificationUri()。
结果是CursorAdapter 收到大量通知,导致 UI 更新过于频繁,从而产生烦人的闪烁效果。
理想情况下,当批处理操作正在进行时,应该有一种方法只在任何批处理操作结束时通知ContentObserver,而不是在每个插入命令时通知。
有人知道这是否可能吗?请注意,我可以更改 ContentProvider 实现并覆盖其任何方法。
【问题讨论】:
-
考虑在SQLiteContentProvider 之类的东西上做/基于你的提供者——它提供了一个基于 SQLite 的优秀和功能提供者的大部分基础——如果你这样做——你应该简单地使用 bulkInsert 或 applyBatch做你的“大量插入”。额外的好处是您的批量插入将在事务中执行,这会大大加快它们的速度。
-
@Jens 非常感谢您的指点,这看起来正是我所追求的。只是一个问题:谁开发并发布了这个代码?从标题看,它似乎是 Android 开源项目的一部分,但是,如果是这样,为什么 Google 没有发布标准 Android SDK?
-
它是 AOSP 项目的一部分,但未在 SDK 中发布 - 为什么我不知道,因为包含它会阻止很多人编写他们自己的蹩脚的
ContentProvider实现。 -
我刚刚添加了一个关于此的功能请求问题:code.google.com/p/android/issues/detail?id=28597
-
为什么@Jens 不将他的评论移至回答,而 Lorenzo Polidori 接受它作为答案。这对社区有好处。
标签: android sqlite android-contentprovider android-cursor android-cursoradapter