Указатель.ошибка 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);
Есть идеи, как курсор может выйти из строя в середине цикла?
2 ответов:
Похоже, что вы делаете довольно большой запрос: по крайней мере, 1127 строк и для всех возможных столбцов (несмотря на то, что вы используете только два из них). И, во время работы с этим
Как отмечает Пракаш,Cursor, Вы делаете дисковый ввод-вывод и/или IPC обратно кContentProvider, предполагая, чтоUsefulDocumentFileсвязано сDocumentFileAndroid.Cursor, который вы получаете обратно, может содержать только подмножество информации. Как только вы попытаетесь продвинуться дальше этой точки,Cursorдолжен вернуться к источнику данных и получите следующее окно результатов. Я вижу, что вы столкнетесь с такой проблемой, если во время этой работы произошли существенные изменения в данных (например, теперь осталось меньше 1127 строк).Я предлагаю вам:
Ограничьте столбцы, которые вы возвращаете к нужному подмножеству, и
Избегайте ввода-вывода во время цикла (например, спин через
Cursor, чтобы построитьArrayList<Pair>или что - то, закройтеCursor, затем повторите список)
Может быть вы srote файл в базе данных вот почему вы получаете
java.lang.IllegalStateExceptionUsefulDocumentFile file = UsefulDocumentFile.fromUri(c, uri);Android SQLite возвращает строки в окнах курсоров, максимальный размер которых составляет 2 МБ, как указано config_cursorWindowSize .Если ваша строка превышает это ограничение, вы получите эту ошибку.
Хранить файлы в файловой системе и пути в базе данных.
Comments