当前位置: 首页 > 知识库问答 >
问题:

Android sqlite更新blob后无法读取

陈宜修
2023-03-14

    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个答案

公羊宗清
2023-03-14

您的问题很可能是由于图像的大小和一个怪癖,因为没有更好的术语,您可以存储大的blob而没有问题,但由于Android的光标窗口的大小限制为2M,您可能无法检索blob。这有时会与一些SQLiteDatabase/Cursor(本例中是CursorgetBlob()或它的底层方法)方法复合,这些方法基本上隐藏了底层故障,以便提供通常更简单的开发体验。

如果您使用了SQLiteDatabaseDatabaseutils.dumpCursor,这可能会突出显示SQLiteDatabase查询方便方法可能隐藏的问题。所以加上:-

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

可能提供线索。

我能想到3个选择:-

  1. 不是将文件存储为BLOB,而是将文件存储为磁盘上的文件,并将路径存储在数据库中。
  2. 显著减小图像的大小。
  3. 研究如何使用C++和本机SQLIte3库将Blob检索到适当大小的容器中。
 类似资料:
  • 问题内容: 我刚刚将Android Studio更新为内部版本130.729444,并且我的项目(在更新之前正确构建)已停止工作,并且Android Studio向我显示以下错误: 有人知道如何解决吗?我正在考虑恢复到旧版本,但是我想知道这是我的问题还是我不​​是唯一的问题。 问题答案: 我最近向Google提交了错误报告。根据Android开发人员工具论坛中的主题,这是他们无法直接解释的问题。我

  • 我已经在Eclipse中运行了对已安装特性的更新。现在Eclipse不会启动。我已经删除了.lock文件。我没有.快照文件。我已经重新安装并解压缩了eclipse以替换我当前的eclipse目录。下面是我使用-clean运行eclipse后的.log文件: !session 2012-11-07 10:11:05.302---------------------------------------

  • 我正在开发一个倒计时应用程序,目前正在尝试在倒计时运行时退出应用程序时显示通知。相应地,我希望在用户返回应用程序时通知消失。 到目前为止,我已经设法使它适用于带有静态文本的简单通知,执行以下操作:在MainActivity.java中,在onStop()中,我创建一个意图并使用start Service(意图)启动服务。对称地,在onStart()中,我运行stop Service(意图),以便当

  • 将我的项目更新为3级,并生成了此错误 java.lang.runtimeException:java.lang.runtimeException:com.android.builder.dexing.dexArchivEmergerException:无法合并dex 在Gradle2.3中不显示此错误 build.gradle应用程序应用插件:'com.android.application' B

  • 问题内容: 我在Mac上使用Flask(python软件包)时,第一次写css时显示正常。但是,当我更新它并尝试检查它时,我只看到第一个CSS样式。我尝试重新启动终端,以及重新安装Flask。有什么建议?谢谢。以下是HTML: 这是CSS: 问题答案: 如前所述,问题与浏览器缓存有关。 为了解决这个问题,你可以向静态(css,js)链接中添加一些动态变量。我更喜欢每个文件的上次修改时间戳。 这是一