I get a IllegalStateException when changing orientation. I have a listView using a SimpleCursorAdapter and a ContentProvider. Any ideas what causes this exception?
EDIT
I must've changed something since I only see the exception when selecting an item from the actionbar spinner and then change the orientation. the action bar spinner has three items: Show All, Show Date, Show Location
When the user selects one, it queries the database (see onNavigationItemSelected()). I tried closing the cursor in onStop() but that didn't solve the problem. Where would be the right place to close it?
in MainActivity:
private Cursor mCursor = null;
public void onCreate() {
mSimpleCursorAdapter = new SpecialAdapter(this,
R.layout.row,
null,
//cursor,
PROJECTION,
new int[] { R.id.titleID, R.id.dateTimeOrLocationID1 , R.id.dateTimeOrLocationID2 },
CursorAdapter.NO_SELECTION);
mListView = (ListView) findViewById(android.R.id.list);
mListView.setAdapter(mSimpleCursorAdapter);
mOnNavigationListener = new OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(int position, long itemId) {
switch(position) {
case 0:
mCursor = getContentResolver().query(ReminderContentProvider.CONTENT_URI, PROJECTION, null, null, null);
break;
case 1:
mCursor = getContentResolver().query(ReminderContentProvider.CONTENT_URI, PROJECTION, " Date NOT NULL", null, null);
break;
case 2:
mCursor = getContentResolver().query(ReminderContentProvider.CONTENT_URI, PROJECTION, " Address NOT NULL", null, null);
break;
default:
break;
}
getLoaderManager().restartLoader(0, null, MainActivity.this);
return true;
}
};
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader loader = new CursorLoader(this, ReminderContentProvider.CONTENT_URI, PROJECTION, null, null, null);
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mSimpleCursorAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mSimpleCursorAdapter.swapCursor(null);
}
SimpleCursorAdapter:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Cursor mCursor = (Cursor) getItem(position); // exception
if(mCursor != null)
{
........
}
}
EDIT
E/ACRA ( 3348): com.example.locationreminder fatal error : attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, Title, Date, Address, Radius, Repetition FROM reminder
E/ACRA ( 3348): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, Title, Date, Address, Radius, Repetition FROM reminder
E/ACRA ( 3348): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
E/ACRA ( 3348): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
E/ACRA ( 3348): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:151)
E/ACRA ( 3348): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
E/ACRA ( 3348): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:213)
E/ACRA ( 3348): at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:162)
E/ACRA ( 3348): at android.widget.CursorAdapter.getItem(CursorAdapter.java:207)
E/ACRA ( 3348): at com.example.locationreminder.SpecialAdapter.getView(SpecialAdapter.java:51)
E/ACRA ( 3348): at android.widget.AbsListView.obtainView(AbsListView.java:2271)
E/ACRA ( 3348): at android.widget.ListView.makeAndAddView(ListView.java:1769)
I am not sure this is the reason of failure, but there is clearly bug in your code: you try to mix manual cursor management with loader. In OnNavigationItemSelected
you call changeCursor
. There are several problems:
changeCursor
closes old cursor. But this cursor is owned by loader, you shouldn't close it, it will be closed by loader after it calls OnLoadFinished
What you should do in OnNavigationItemSelected
is to restart loader with new query parameters.