Android中CustomAdapter(继承BaseAdapter)删除SQLite行异常问题
解决ListView条目删除成功但SQLite删除崩溃/无效的问题
看起来你遇到的核心问题是混淆了ListView的position和数据库行的唯一标识,直接传position去删数据库肯定会出问题——要么删错行、要么找不到行导致崩溃,咱们一步步来解决:
第一步:先理清楚核心错误
你现在调用dba.removeData(position),这里的position是ListView中条目的位置,和SQLite数据库里的行没有直接对应关系。比如你删过几次条目后,数据库的行ID和列表的position就完全对不上了,用它删数据库自然要么删不到,要么触发异常崩溃。
第二步:修改删除逻辑的正确姿势
首先确保你的Model类里有数据库表的主键字段(比如id,这是数据库里唯一标识每一行的字段,通常是自增的),然后按下面的步骤改:
- 获取对应条目的Model对象,拿到它的主键ID:
// 先拿到要删除的那条数据的Model实例 Model targetModel = mModel.get(position); // 从Model里取出数据库对应的主键ID(假设你的Model里有getId()方法) int targetId = targetModel.getId();
- 调用数据库删除方法时传主键ID,不是position:
// 用主键ID删数据库里的对应行 dba.removeData(targetId); // 再更新ListView的数据 mModel.remove(position); notifyDataSetChanged();
第三步:修复DatabaseHelper里的removeData方法
你的removeData方法之前应该是用position当ID来删的,现在要改成用主键匹配:
public class DatabaseHelper extends SQLiteOpenHelper { // ...其他代码... public void removeData(int targetId) { SQLiteDatabase db = this.getWritableDatabase(); // 替换成你的表名和主键字段名,比如表名叫"your_table",主键是"id" db.delete("your_table", "id = ?", new String[]{String.valueOf(targetId)}); db.close(); } }
这里的
?是占位符,避免SQL注入,同时保证语法正确,别直接拼接字符串!
第四步:排查崩溃的额外问题
如果还是崩溃,建议:
- 加个try-catch捕获异常,看看具体错误:
try { Model targetModel = mModel.get(position); dba.removeData(targetModel.getId()); mModel.remove(position); notifyDataSetChanged(); } catch (Exception e) { e.printStackTrace(); // 看Logcat里的异常信息,能快速定位问题 // 也可以加个Toast提示用户删除失败 Toast.makeText(context, "删除失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); }
- 检查
dba实例有没有正确初始化,比如在CustomAdapter的构造函数里是不是已经new了DatabaseHelper:
public CustomAdapter(Context context, ArrayList<Model> mModel) { this.context = context; this.mModel = mModel; this.dba = new DatabaseHelper(context); // 确保这里没写错! }
最后小提醒
如果之后遇到数据库和ListView数据不一致的情况,删除后最好重新从数据库查询一遍数据,再更新mModel并调用notifyDataSetChanged(),这样能保证数据完全同步~
内容的提问来源于stack exchange,提问作者Arkadiusz Skorek
相关产品推荐
相关产品推荐

