Android应用点击关闭按钮崩溃:已关闭Cursor重新查询异常
嘿,我仔细看了你的问题描述、代码和错误日志,问题的核心很清晰:当你关闭Editor Activity回到MainActivity时,系统尝试重新查询一个已经被关闭的SQLiteCursor,触发了IllegalStateException,直接导致应用崩溃。
问题根源分析
从错误日志的核心栈信息就能定位问题:
java.lang.IllegalStateException: trying to requery an already closed cursor android.database.sqlite.SQLiteCursor@2e3a8e12
这种情况几乎都是因为你的ListView使用了CursorAdapter(或它的子类比如SimpleCursorAdapter),而你在MainActivity的onPause/onStop这类生命周期方法里手动关闭了cursor。当Activity从Editor返回并执行onResume时,系统会自动尝试重新查询这个已经被关闭的cursor,从而抛出异常。
另外,你的onContextItemSelected代码里还有个明显的逻辑笔误:EDIT_ID的分支是空的,反而在DELETE_ID分支里处理了跳转Editor的逻辑,这会导致点击“编辑”选项没反应,点击“删除”却跳转到编辑页面,这个也得同步修正。
解决方案
1. 先修正上下文菜单的逻辑笔误
把onContextItemSelected里的分支对应关系改正确,让编辑选项绑定对应的跳转逻辑:
public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); if(item.getItemId() == EDIT_ID){ // 编辑逻辑:跳转到Editor Activity Intent intent = new Intent(getContext(), Editor.class); intent.putExtra("POSITION", acmi.position); startActivity(intent); } else if(item.getItemId() == DELETE_ID){ // 这里编写删除对应的业务逻辑 } return super.onContextItemSelected(item); }
2. 正确管理Cursor的生命周期
推荐使用Android官方的LoaderManager + CursorLoader来加载cursor,这是最安全且符合规范的方式——它会自动处理cursor的创建、销毁和重新查询,完全避免手动管理cursor带来的生命周期冲突问题。
如果你暂时不想切换到Loader方案,也可以做以下调整:
- 不要在
onPause或onStop方法里关闭cursor,把关闭cursor的操作移到onDestroy方法中(确保Activity彻底销毁时才释放资源)。 - 在MainActivity的
onResume方法里,重新查询cursor并更新Adapter,确保cursor处于有效状态:
@Override protected void onResume() { super.onResume(); // 假设你有自定义方法getNewCursor()用于获取最新的查询结果 Cursor newCursor = getNewCursor(); // 替换Adapter里的旧cursor,系统会自动关闭旧cursor yourCursorAdapter.changeCursor(newCursor); }
总结
先修正上下文菜单的逻辑错误,再通过LoaderManager或者调整cursor的生命周期管理方式,就能彻底解决返回Activity时的崩溃问题啦。
内容的提问来源于stack exchange,提问作者Abu-Bakr




