Android sqlite не может прочитать после обновления BLOB-объекта - PullRequest
0 голосов
/ 01 июня 2018

Я хочу сохранить изображение (размер около 10 МБ) в базе данных SQLite.Для этого я создал помощника по БД Dao.Все работает отлично, я могу создать несколько записей и прочитать их без проблем, я даже могу обновить 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)

Я подозреваю, что обновление большого двоичного объекта в строке как-то повредит базу данных.Кто-нибудь сталкивался с подобной проблемой?Если да, то как ты решил это?

1 Ответ

0 голосов
/ 01 июня 2018

Скорее всего, ваша проблема связана с размером изображения и причудой, из-за отсутствия лучшего термина, что вы можете хранить большие 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 в контейнер подходящего размера.

Возможно, это могут быть некоторые библиотеки, которые делают это.Тем не менее, я не помню ни одного упоминания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...