Android 为什么我的碎片在重新加载加载程序时会崩溃?
虽然我一直无法复制这个bug,但我仍然会收到一些发生这种情况的崩溃报告。我以为为我的列表适配器添加一个空检查可以修复它,但它仍然在发生。我错过了什么 完整堆栈跟踪:Android 为什么我的碎片在重新加载加载程序时会崩溃?,android,android-fragments,android-loadermanager,Android,Android Fragments,Android Loadermanager,虽然我一直无法复制这个bug,但我仍然会收到一些发生这种情况的崩溃报告。我以为为我的列表适配器添加一个空检查可以修复它,但它仍然在发生。我错过了什么 完整堆栈跟踪: public void onLoaderReset(加载程序){ final int id=loader.getId(); 开关(id){ 案例加载器\u ID1: 如果(mAdapter!=null) mAdapter.changeCursor(null);//stacktrace引用的第512行 打破 案例加载器\u ID2:
public void onLoaderReset(加载程序){
final int id=loader.getId();
开关(id){
案例加载器\u ID1:
如果(mAdapter!=null)
mAdapter.changeCursor(null);//stacktrace引用的第512行
打破
案例加载器\u ID2:
//这里还有其他代码
打破
违约:
抛出新的InvalidParameterException(“id=”+id);
}
}
mAdapter是在onActivityCreated中初始化的,但我意识到在键入此命令时,我从未发布过它,也许我应该在OnDetch中执行此操作?mAdapter附加到由ListFragment设置的ListView。我将适配器光标设置为null以清除我的列表。那么,是的,我忽略了什么呢?在搜索了Android源代码之后,我现在明白了,就像GreyBearedGeek所说的那样,我应该允许加载程序处理光标销毁 正如您在CursorLoader中看到的,如果传递新光标,它将处理关闭旧光标的问题:
/* Runs on the UI thread */
@Override
public void deliverResult(Cursor cursor) {
if (isReset()) {
// An async query came in while the loader is stopped
if (cursor != null) {
cursor.close();
}
return;
}
Cursor oldCursor = mCursor;
mCursor = cursor;
if (isStarted()) {
super.deliverResult(cursor);
}
if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
oldCursor.close();
}
}
以及在重置时关闭光标
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
if (mCursor != null && !mCursor.isClosed()) {
mCursor.close();
}
mCursor = null;
}
因此,我将在将来使用swapCursor,以避免干扰游标装载机的处理,尽管我还不知道这是如何导致我的NPE出现在上面的堆栈跟踪中。我无法想象它是您的NPE的来源,但是我认为您应该使用
swapCursor
而不是changeCursor
,因为加载程序“拥有”光标并将其关闭swapCursor
不会关闭旧的游标,而changeCursor
会关闭。我明白你现在说的话,我会看看是否可以复制它,这样我就可以尝试你的解决方案。当然,54142()问题表明了我认为会发生的事情。好吧,这是一个我(我想大多数人)不知道的非常严重的错误:-)
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
if (mCursor != null && !mCursor.isClosed()) {
mCursor.close();
}
mCursor = null;
}