Указатель.ошибка moveToNext



Я вижу отчет об аварии для этого эпизодически:



Fatal Exception: java.lang.IllegalStateException: Couldn't read row 1127, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(CursorWindow.java)
at android.database.CursorWindow.getLong(CursorWindow.java:511)
at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220)
at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)
at android.database.CursorWrapper.moveToNext(CursorWrapper.java:166)
at com.anthonymandra.util.ImageUtils.cleanDatabase(SourceFile:381)


Очевидно, что moveToNext терпит неудачу в середине цикла (обратите внимание на строку 1127). Цикл удаляет записи, представляющие файлы, которые больше не могут быть найдены.



final ArrayList<ContentProviderOperation> operations = new ArrayList<>();

try( Cursor cursor = c.getContentResolver().query(Meta.CONTENT_URI, null, null, null, null))
{
if (cursor == null)
return;

final int uriColumn = cursor.getColumnIndex(Meta.URI);
final int idColumn = cursor.getColumnIndex(BaseColumns._ID);

while (cursor.moveToNext())
{
String uriString = cursor.getString(uriColumn);
if (uriString == null) // we've got some bogus data, just remove
{
operations.add(ContentProviderOperation.newDelete(
Uri.withAppendedPath(Meta.CONTENT_URI, cursor.getString(idColumn))).build());
continue;
}
Uri uri = Uri.parse(uriString);
UsefulDocumentFile file = UsefulDocumentFile.fromUri(c, uri);
if (!file.exists())
{
operations.add(ContentProviderOperation.newDelete(Meta.CONTENT_URI)
.withSelection(getWhere(), new String[]{uriString}).build());
}
}
}

c.getContentResolver().applyBatch(Meta.AUTHORITY, operations);


Есть идеи, как курсор может выйти из строя в середине цикла?

749   2  

2 ответов:

Похоже, что вы делаете довольно большой запрос: по крайней мере, 1127 строк и для всех возможных столбцов (несмотря на то, что вы используете только два из них). И, во время работы с этим Cursor, Вы делаете дисковый ввод-вывод и/или IPC обратно к ContentProvider, предполагая, что UsefulDocumentFile связано с DocumentFile Android.

Как отмечает Пракаш, Cursor, который вы получаете обратно, может содержать только подмножество информации. Как только вы попытаетесь продвинуться дальше этой точки, Cursor должен вернуться к источнику данных и получите следующее окно результатов. Я вижу, что вы столкнетесь с такой проблемой, если во время этой работы произошли существенные изменения в данных (например, теперь осталось меньше 1127 строк).

Я предлагаю вам:

  • Ограничьте столбцы, которые вы возвращаете к нужному подмножеству, и

  • Избегайте ввода-вывода во время цикла (например, спин через Cursor, чтобы построить ArrayList<Pair> или что - то, закройте Cursor, затем повторите список)

Может быть вы srote файл в базе данных вот почему вы получаете java.lang.IllegalStateException

 UsefulDocumentFile file = UsefulDocumentFile.fromUri(c, uri);

Android SQLite возвращает строки в окнах курсоров, максимальный размер которых составляет 2 МБ, как указано config_cursorWindowSize .Если ваша строка превышает это ограничение, вы получите эту ошибку.

Хранить файлы в файловой системе и пути в базе данных.

Comments

    Ничего не найдено.