You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android应用点击关闭按钮崩溃:已关闭Cursor重新查询异常

解决Android返回Activity时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方案,也可以做以下调整:

  • 不要在onPauseonStop方法里关闭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

火山引擎 最新活动