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

Android SQLite Cursor初始索引-1越界报错问题求助

问题排查结果

直接崩溃原因

  • 游标未移动即读取数据:Android SQLite返回的Cursor初始位置固定为-1,指向第一条查询结果的前置位置,必须主动调用移动方法将游标指向有效行才能读取数据。原有遍历逻辑仅做次数循环,全程未移动游标,游标始终停在-1位置,直接触发CursorIndexOutOfBoundsException。
  • 列索引查询参数错误:dbOpener类中定义的数据库实际列名为ITEM/URGENT/_id,但MainActivity中调用getColumnIndex()时传入的是Java常量名字符串"COL_ITEM_NAME"/"COL_URGENT"/"COL_ID",数据库中不存在对应列名,返回的列索引全为-1,即便游标位置正确也无法读取数据。

其他连带逻辑缺陷

  • 数据加载时机错误:数据库读取操作在ListView绑定空adapter之后执行,读取完成后未调用刷新方法,历史存储的数据不会显示到列表中。
  • 游标未关闭:读取完数据未主动关闭Cursor,会造成内存泄漏。
  • 删除逻辑不同步:长按删除仅移除了内存集合中的条目,未同步删除数据库中对应记录,应用重启后被删除的内容会重新出现。
  • dbOpener中预定义的columns数组重复写入COL_ITEM_NAME、遗漏_id字段,后续如果用该数组做查询参数会触发列不存在错误。
  • 紧急状态Switch监听逻辑错误:原有点击监听强制把开关设为选中状态,用户无法切回非紧急状态,交互失效。
修复代码

1. 替换数据库读取遍历逻辑

将MainActivity中原有读取Cursor的代码替换为如下内容:

cursor = dbOpener.readData();
// 直接引用dbOpener中定义的列名常量,避免硬编码字符串写错
int nameColIndex = cursor.getColumnIndex(dbOpener.COL_ITEM_NAME);
int urgentColIndex = cursor.getColumnIndex(dbOpener.COL_URGENT);
int idColIndex = cursor.getColumnIndex(dbOpener.COL_ID);

// 先移动到首行判断是否有数据,循环中主动移动游标到下一行
if (cursor.moveToFirst()) {
    do {
        String name = cursor.getString(nameColIndex);
        int urgentHolder = cursor.getInt(urgentColIndex);
        boolean isUrgent = urgentHolder == 1;
        arrayList.add(new toDoItem(name, isUrgent));
    } while (cursor.moveToNext());
}
// 用完关闭游标
cursor.close();
// 加载完数据刷新列表
adapter.notifyDataSetChanged();

2. 修正dbOpener中的列数组

将原有错误的columns定义替换为:

String [] columns = {dbOpener.COL_ID, dbOpener.COL_ITEM_NAME, dbOpener.COL_URGENT};

3. 修正Switch交互逻辑

删除原有的urgent.setOnClickListener代码,替换为选中状态监听:

urgent.setOnCheckedChangeListener((buttonView, isChecked) -> urgent.setChecked(isChecked));

4. 补充删除的数据库同步逻辑

在长按删除的正按钮回调中,增加数据库删除操作,保证内存和数据库数据一致。


内容的提问来源于stack exchange,提问作者ReginaldRey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:00:56