首页 文章

更新blob后,Android sqlite无法读取

提问于
浏览
-1

我想在SQLite数据库中存储一个图像(大小约10MB) . 为此,我创建了一个DB助手,一个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

    您的问题很可能是由于图像的大小和怪癖,因为想要更好的术语,您可以存储2m的大型BLOB 's without issue, but due to the size limitations of an Android'光标窗口,您可能无法检索BLOB . 这有时会使一些SQLiteDatabase / Cursor(在这种情况下为Cursor getBlob() 或它的底层方法)基本上隐藏底层故障,以提供通常更简单的开发体验 .

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

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

    可以提供线索 .

    我可以想到3个选项: -

    • 不是将文件存储为BLOBS,而是将文件作为文件存储在磁盘上并将路径存储在数据库中 .

    • 显着减小图像的大小 .

    • 查看使用C和本机SQLIte3库将BLOBS检索到适当大小的容器中 .

    也许可能是一些图书馆这样做 . 但是,我不记得有任何提及 .

相关问题