Loader#stopLoading()
的Android文档说:
在LoaderManager中使用Loader时,必须不要调用此方法 你自己,或者你会对Loader的管理产生冲突。
但这是真的吗?具体来说,我对CursorLoader
感兴趣。我通过Android源代码查看了4.2版本,看起来非常温和。有没有人尝试过使用这种方法并看到了问题?如果我想保持当前活动Cursor最后由CursorLoader传递,并且由于内部ContentObserver
被触发而暂时停止重新加载,是否有替代方法?基本上我想对ContentProvider进行一系列更改,这是对这个托管Cursor的源代码,我不希望Loader在完成之前开始大量的负载。
答案 0 :(得分:1)
我同意a.ch依赖Android源代码的方式并不是因为您冒着使用未来更新破坏应用程序的风险,而且因为Android的数百个修改版本(碎片化的乐趣) )。 stopLoading()无论如何都不会起作用,原因见下文。
cancelLoad()不会关闭底层游标(你从哪里得到它?)所以虽然这个方法会在一个正在进行时取消一个加载,但它不会阻止未来的加载。即使它会阻止未来的加载它也不会起作用(出于同样的原因,stopLoading()将无效)。
我最初想要解决这个问题的方法是实现一个自定义的CursorLoader,并使用一个标志覆盖onContentChanged()方法,以决定是否“接受”更改。这样可以暂时禁用更新:
class MyCursorLoader extends CursorLoader {
private boolean mDontUpdate;
public MyCursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
super(context, uri, projection, selection, selectionArgs, sortOrder);
}
@Override
public void onContentChanged () {
if (! mDontUpdate) {
super.onContentChanged();
}
}
@Override
public boolean takeContentChanged () {
return mDontUpdate ? false : super.takeContentChanged();
}
void dontUpdate(boolean dontUpdate) {
mDontUpdate = dontUpdate;
}
}
您可以在onCreateLoader(int,Bundle)中使用此类而不是CursorLoader,并在数据库更新期间设置不更新标志。
现在它的效果很好,但事实并非如此。虽然从问题中不清楚CursorLoader和结果Cursor的用途我假设Cursor用于ListView或类似小部件的CursorAdapter。 小部件将自己的ContentObserver注册到Cursor并相应地更新视图。因此,即使没有加载新的Cursor,ListView(GridView或附加到Cursor的任何其他小部件)仍然会更新(Android会在CursorAdapter中调用newView,bindView方法)。
这让我想到了我的下一个方法。 虽然从你的问题不清楚,我假设你正在对数据库进行一些修改?如果是这种情况那么为什么不在一次交易中进行所有修改呢?如果在一个事务中完成,则在事务提交之前,任何地方都不会显示更改,这可能就是您想要的。
如果你的Cursor没有数据库支持,你可能不得不在更新期间从你的小部件中删除适配器。
答案 1 :(得分:0)
首先,你不应该依赖android源代码:如果当前的android构建没有任何问题,那并不意味着将来不会有任何问题。我建议将android系统视为一个黑盒子,这样可以让你编写健壮可靠的应用程序。
根据您对替代方案的提问,请考虑cancelLoad()
。