Что может вызвать StaleDataException, кроме преждевременного вызова cursor.close()?
В настоящее время я сильно модифицирую/переписываю приложение для Android, и я видел случайный крах в следующих строках: вызывается метод CursorAdapter
, он вызывает AbstractWindowedCursor#checkPosition()
и:
02-20 15:03:18.180 E/AndroidRuntime(17143): android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.
02-20 15:03:18.180 E/AndroidRuntime(17143): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139)
02-20 15:03:18.180 E/AndroidRuntime(17143): at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:74)
02-20 15:03:18.180 E/AndroidRuntime(17143): at android.database.CursorWrapper.getLong(CursorWrapper.java:106)
02-20 15:03:18.180 E/AndroidRuntime(17143): at android.widget.CursorAdapter.getItemId(CursorAdapter.java:220)
Проблема в том, что мы не закрываем Cursor
s. Все наши Cursor
исходят от CursorLoader
и, в свою очередь, производятся с помощью ContentProvider
. Мы передаем Cursor
в каждый соответствующий CursorAdapter
из LoaderCallbacks
, мы регистрируем Cursor
для уведомлений в ContentProvider
, мы уведомляем ContentResolver
из каждого insert(...)
, delete(...)
и update(...)
... Короче говоря, я не могу найти причин, по которым закрывался Cursor
во время использования.
Итак: каковы другие причины StaleDataException
?
Ответы
Ответ 1
если вы вызвали Context.managedQuery()
в android 4.0 и выше, вы не должны вызывать Cursor.close()
, если вы это сделаете, StaleDataException
будет выбрано, вы можете изменить код следующим образом:
if(VERSION.SDK_INT < 14) {
cursor.close();
}