【问题标题】:Android sqlite unable to read after updating a blob更新 blob 后,Android sqlite 无法读取
【发布时间】:2018-11-11 02:07:11
【问题描述】:
我想在 SQLite 数据库中存储一个图像(大小约为 10MB)。为此,我创建了一个 DB 助手,一个 Dao。一切正常,我可以创建多条记录并毫无问题地读取它们,我什至可以毫无问题地更新最新记录中的 blob。
但是,如果我返回旧记录并更新 blob,我将无法再使用 blob 加载此记录。
我有一个显示所有记录的列表视图,为此我使用不返回 blob 的选择。此列表工作正常,但是当我单击列表中的某个项目时,我尝试使用 blob 加载记录,光标返回 0 行。
公共无效保存(比尔比尔){
ContentValues 值 = 新 ContentValues();
values.put(DatabaseHelper.BILL_NAME_COLUMN, aBill.getName());
values.put(DatabaseHelper.BILL_DUE_DATE_COLUMN, getContentValue(aBill.getDueDate()));
values.put(DatabaseHelper.BILL_IMAGE_COLUMN, aBill.getImage());
if (!aBill.isPersistent()) {
aBill.setId(database.insert(DatabaseHelper.BILL_TABLE, null, values));
abill.setpersistent(真实);
} 别的 {
database.update(DatabaseHelper.BILL_TABLE, values, DatabaseHelper.BILL_ID_COLUMN + "=?", new String[]{String.valueOf(aBill.getId())});
}
}
// 更新 blob 后失败
公共账单得到(长ID){
光标 cursor = database.query(DatabaseHelper.BILL_TABLE,
新字符串 [] {DatabaseHelper.BILL_ID_COLUMN,DatabaseHelper.BILL_NAME_COLUMN,DatabaseHelper.BILL_DUE_DATE_COLUMN,DatabaseHelper.BILL_IMAGE_COLUMN},“id = ?”,新字符串 [] {String.valueOf(id)},空,
空,DatabaseHelper.BILL_DUE_DATE_COLUMN);
比尔比尔= null;
while (cursor.moveToNext()) {
比尔=新比尔();
Bill.Setpersistent(True);
bill.setId(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.BILL_ID_COLUMN)));
bill.setName(cursor.getString(cursor.getColumnIndex(DatabaseHelper.BILL_NAME_COLUMN)));
bill.setDueDate(getDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.BILL_DUE_DATE_COLUMN))));
bill.setImage(cursor.getBlob(cursor.getColumnIndex(DatabaseHelper.BILL_IMAGE_COLUMN)));
}
cursor.close();
返回账单;
}
//更新blob后工作正常
公共列表pindall(){
列出账单 = new ArrayList();
光标 cursor = database.query(DatabaseHelper.BILL_TABLE,
新字符串 [] {DatabaseHelper.BILL_ID_COLUMN,DatabaseHelper.BILL_NAME_COLUMN,DatabaseHelper.BILL_DUE_DATE_COLUMN},空,空,空,
空,DatabaseHelper.BILL_DUE_DATE_COLUMN);
while (cursor.moveToNext()) {
比尔比尔=新比尔();
Bill.Setpersistent(True);
bill.setId(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.BILL_ID_COLUMN)));
bill.setName(cursor.getString(cursor.getColumnIndex(DatabaseHelper.BILL_NAME_COLUMN)));
bill.setDueDate(getDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.BILL_DUE_DATE_COLUMN))));
Bills.add(比尔);
}
cursor.close();
退货;
}
这是一个例外:
java.lang.IllegalStateException:无法从 CursorWindow 读取第 0 行第 0 列。确保在从光标访问数据之前正确初始化光标。
在 android.database.CursorWindow.nativeGetLong(本机方法)
在 android.database.CursorWindow.getLong(CursorWindow.java:511)
在 android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
在 net.rka.android.billreminder.BillDao.get(BillDao.java:106)
我怀疑连续更新 blob 会以某种方式损坏数据库。
有没有人遇到过类似的问题?如果有,你是怎么解决的?
【问题讨论】:
-
-
日志中是否有堆栈跟踪,如果有,请添加。图片有多大?作为仅在读入游标时适用的限制,而不是在插入/更新列时,如果内存服务,CursorWindow 可以容纳 1 或 2m 的数据大小(因此通常只看到 BLOB)
-
添加了堆栈跟踪。日志中没有以前的错误。正如我所说的,它工作正常,我可以毫无问题地添加具有相同大小图像的新记录。我可以打开它们。我什至可以一遍又一遍地更新最后一条记录并加载它们。但是当我更新以前的记录之一时,这些记录无法打开。光标不包含记录。
-
尝试在while (cursor.moveToNext()) { .... 之前添加DatabaseUtils.dumpCursor(cursor);。输出将在日志中。还可以尝试从查询中省略图像,看看是否有效。
-
10Mb 图像大小很可能会导致问题。最多大约和平均大约 100k 然后可以将图像存储在数据库中。再大一点,你应该真正将图像存储为文件并将路径存储在数据库中。
标签:
android
sqlite
blob