StaleDataException with dialog

I am trying to show a list dialog with names from my database, but I keep getting a StaleDataException . I know that usually this means that I try to use data from a closed cursor, but the cursor does not close until I get all the data, so I don’t understand why I get this

 d = new Dialog(this); d.setContentView(R.layout.dialog_layout); d.setTitle("Select Bowler"); ListView lv = (ListView)d.findViewById(R.id.dialog_list); Cursor c = getContentResolver().query( BowlersDB.CONTENT_URI, new String[] { BowlersDB.ID, BowlersDB.FIRST_NAME, BowlersDB.LAST_NAME }, null, null, BowlersDB.LAST_NAME + " COLLATE LOCALIZED ASC" ); if (c.moveToFirst() && c != null) { SimpleCursorAdapter adapter = new SimpleCursorAdapter( this, R.layout.names_listview, c, new String[] { BowlersDB.FIRST_NAME, BowlersDB.LAST_NAME }, new int[] { R.id.bListTextView, R.id.bListTextView2 }, 0 ); lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View v, int position, long id) { bowlerClickedID = id; updateName(id); } }); d.show(); } c.close(); 

Mistake

 android.database.StaleDataException: Attempting to access a closed CursorWindow. Most probable cause: cursor is deactivated prior to calling this method. at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139) at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50) at android.database.CursorWrapper.getString(CursorWrapper.java:114) at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:150) at android.widget.CursorAdapter.getView(CursorAdapter.java:250) at android.widget.AbsListView.obtainView(AbsListView.java:2267) at android.widget.ListView.measureHeightOfChildren(ListView.java:1244) at android.widget.ListView.onMeasure(ListView.java:1156) at android.view.View.measure(View.java:15172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390) at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) at android.view.View.measure(View.java:15172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:15172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390) at android.widget.LinearLayout.measureVertical(LinearLayout.java:681) at android.widget.LinearLayout.onMeasure(LinearLayout.java:574) at android.view.View.measure(View.java:15172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148) at android.view.View.measure(View.java:15172) ... 

EDIT: If I comment on the c.close() , it works fine, but I can't just leave the cursor open, although what should I do?

+7
source share
3 answers

You cannot close the cursor until the CursorAdapter is no longer needed. Therefore, you can close it in the onDestroy () method:

 @Override public void onDestroy() { super.onDestroy(); ListView lv = (ListView) d.findViewById(R.id.dialog_list); ((CursorAdapter) lv.getAdapter()).getCursor().close(); database.close(); } 
+4
source

You get your error because you close Cursor , and the generated SimpleCursorAdapter may still try to access it.

If you want to use CursorLoader , as it should be.

  • Keep the link to your adapter as an instance variable
  • Build your simple cursor adapter with a null reference for the cursor
  • Try to implement the LoaderManager.LoaderCallbacks<Cursor> class
  • Actually create a CursorLoader in onCreateLoader
  • In onLoadFinished() replace adapter.swapCursor(cursor) cursors adapter.swapCursor(cursor)
  • In onLoaderReset() change the cursor with the null cursor as adapter.swapCursor (null) `

You should also put your data in ContentProvider - this is not so bad!

+9
source

I used the startManagingCursor method to leave the problem of opening and closing Cursors in the system. Now that it is deprecated (it still works, but I would not recommend using it), consider using the CursorLoader class with the LoaderManager and leave it in the system to handle cursor closure.

0
source

All Articles