更新blob后,Android sqlite无法读取

时间:2018-06-01 01:19:21

标签: android sqlite blob

我想在SQLite数据库中存储一个图像(大小约为10MB)。为此,我创建了一个数据库助手,一个Dao。一切正常,我可以创建几个记录并毫无问题地阅读它们,我甚至可以毫无问题地更新最新记录中的blob。
但是如果我回到旧的记录并更新blob,我就不能再用blob加载这条记录了。
我有一个列表视图,我显示所有记录,为此我使用一个不返回blob的选择。此列表工作正常,但是当我单击列表中的某个项目时,我尝试使用blob加载记录,光标返回0行。


    public void save(Bill aBill) {
        ContentValues values = new 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(true);
        } else {
            database.update(DatabaseHelper.BILL_TABLE, values, DatabaseHelper.BILL_ID_COLUMN + "=?", new String[]{String.valueOf(aBill.getId())});
        }
    }

    // fails after updating the blob
    public Bill get(long id) {
        Cursor cursor = database.query(DatabaseHelper.BILL_TABLE,
                new String[]{DatabaseHelper.BILL_ID_COLUMN, DatabaseHelper.BILL_NAME_COLUMN, DatabaseHelper.BILL_DUE_DATE_COLUMN, DatabaseHelper.BILL_IMAGE_COLUMN}, "id = ?", new String[] {String.valueOf(id)}, null,
                null, DatabaseHelper.BILL_DUE_DATE_COLUMN);
        Bill bill = null;
        while (cursor.moveToNext()) {
            bill = new Bill();
            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();
        return bill;
    }

    //works fine after updating the blob
    public List findAll() {
        List bills = new ArrayList();
        Cursor cursor = database.query(DatabaseHelper.BILL_TABLE,
                new String[]{DatabaseHelper.BILL_ID_COLUMN, DatabaseHelper.BILL_NAME_COLUMN, DatabaseHelper.BILL_DUE_DATE_COLUMN}, null, null, null,
                null, DatabaseHelper.BILL_DUE_DATE_COLUMN);

        while (cursor.moveToNext()) {
            Bill bill = new Bill();
            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(bill);
        }
        cursor.close();
        return bills;
    }

以下是例外:

java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(Native Method)
at android.database.CursorWindow.getLong(CursorWindow.java:511)
at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
at net.rka.android.billreminder.BillDao.get(BillDao.java:106)

我怀疑连续更新blob会以某种方式破坏数据库 有没有人遇到过类似的问题?如果是这样,你是如何解决的?

1 个答案:

答案 0 :(得分:0)

您的问题很可能是由于图像的大小和怪癖,因为缺少更好的术语,您可以存储大型BLOB而没有问题,但由于尺寸限制Android的2米光标窗口,您可能无法检索BLOB。这有时会加入一些SQLiteDatabase / Cursor (本例中的Cursor getBlob()或它的基础方法)方法基本上隐藏了潜在的失败,以便提供什么是通常是一种更简单的开发经验。

如果您使用了SQLiteDatabase DatabaseUtils.dumpCursor,则可能会突出显示SQLiteDatabase查询便捷方法可能隐藏的问题。所以补充: -

DatabaseUtils.dumpCursor(cursor); //<<<< ADDED
while (cursor.moveToNext()) { ........

可以提供线索。

我可以想到3个选项: -

  1. 不是将文件存储为BLOBS,而是将文件作为文件存储在磁盘上,并将路径存储在数据库中。
  2. 显着缩小图像尺寸。
  3. 查看使用C ++和本机SQLIte3库将BLOBS检索到合适大小的容器中。
  4. 也许可能有些图书馆会这样做。但是,我不记得有人提到过。