I'm currently heavily modifying/rewriting an Android app and I have seen a very occasional crash along the following lines: a CursorAdapter
method is called, it calls AbstractWindowedCursor#checkPosition()
, and:
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)
The trouble is, we're not closing any Cursor
s. All our Cursor
s come from CursorLoader
s and in turn are produced by a ContentProvider
. We're passing the Cursor
into each respective CursorAdapter
from the LoaderCallbacks
, we're registering the Cursor
for notifications in the ContentProvider
, we're notifying the ContentResolver
from each insert(...)
, delete(...)
and update(...)
... in short I can't find any reason why a Cursor
would close while in use.
So: what are the other causes of a StaleDataException
?
Cursor
from outside the adapter provoked this behaviour, even though (again) we never called.close()
or any method that you'd think caused this. Since then, I've always implementedContentObserver
andDataSetObserver
in a manner analogous to android.googlesource.com/platform/frameworks/base/+/master/core/… (skip to the end) if I ever had to use a Cursor both inside and outside an adapter. – Beefwitted