You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发理发店预约应用时保存功能崩溃,报CursorWindow异常

嘿,这个错误我之前帮不少开发者排查过,咱们一步步来解决!

解决理发店应用预约创建时的Cursor崩溃问题

首先先拆解你遇到的错误核心:

E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 2 rows, 3 columns.
java.lang.IllegalStateException: ...

这个错误的本质是你的代码尝试从Cursor中读取一个不存在的列——column -1就表示找不到你指定的列名/索引,而Cursor本身是有2行3列数据的,说明查询本身返回了结果,但你读取列的步骤出了问题。

接下来给你几个最常见的排查和修复方向:

1. 检查Cursor读取的列名是否与数据库表结构完全一致

这是踩坑最多的原因:

  • 确认你在从Cursor取值时用的列名(比如cursor.getString(cursor.getColumnIndex("column_name"))),和创建数据库表时定义的列名完全匹配,包括大小写!Android里的SQLite默认对列名大小写敏感。
  • 举个例子:如果你的预约表列名是appointment_time,但代码里写的是appointmentTime,就会返回-1的列索引,直接触发崩溃。
  • 建议用常量定义列名避免拼写错误,比如:
    public static final String COLUMN_APPOINTMENT_TIME = "appointment_time";
    // 读取时直接用常量
    int timeIndex = cursor.getColumnIndex(COLUMN_APPOINTMENT_TIME);
    if (timeIndex != -1) {
        String time = cursor.getString(timeIndex);
    }
    

2. 确认查询语句包含了你要读取的列

如果查询时没有用SELECT *,而是指定了列,一定要确保你要读取的列在SELECT列表里:

  • 错误示例:SELECT id, customer_name FROM appointments,但之后尝试读取appointment_time列,这肯定找不到。
  • 修复:要么改成SELECT *,要么把需要的列都加到查询语句中。

3. 确保Cursor处于有效行再读取数据

在读取Cursor数据前,必须确认Cursor已经移动到了有效的行:

  • 错误写法:直接在cursor.moveToFirst()之前就读取数据,或者moveToFirst()返回false(Cursor为空)还继续读取。
  • 正确的处理逻辑应该是:
    if (cursor != null && cursor.moveToFirst()) {
        do {
            // 在这里安全读取Cursor的列数据
        } while (cursor.moveToNext());
    }
    // 记得最后关闭Cursor,避免内存泄漏
    if (cursor != null) {
        cursor.close();
    }
    

4. 快速调试技巧:打印Cursor所有列名

实在找不到问题的话,可以在崩溃前打印出Cursor的所有列名,直观对比你代码里用的列名:

String[] columnNames = cursor.getColumnNames();
for (String name : columnNames) {
    Log.d("CursorColumns", "当前Cursor包含列:" + name);
}

内容的提问来源于stack exchange,提问作者Aaron Brat Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:42:50