Java.lang.IllegalStateException: attempt to reopen an already closed object

I am trying to find out why sometimes I get an IllegalStateException. I cannot find good examples showing how to load a list using a thread to query a SQLite database. I have included my code below. In most cases, it works correctly, but sometimes I get an IllegalStateException.

I also got a similar exception in my other activity, which is an instance of ExpandableListActivity. This exception says that "it is trying to request an already closed cursor."

Can someone tell me the correct way to do this so that it doesn't cause any errors? I would prefer to use cursors instead of copying all the data into memory. If I cannot understand this, I will have to load all of this into memory.

I think the problem is with startManagingCursor (Cursor) and the fact that the database connection is closed in onDestroy (). Help plz
- fairy tale

public class MyListActivity extends ListActivity {
    private MyCursorAdapter adapter;
    private SQLiteDatabase db = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            new RetrieveCursorTask(this).execute((Void[]) null);
        } catch (Exception e) {
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // Null out the cursor. 
        if (adapter != null) {
            adapter.changeCursor(null);
            adapter = null;
        }

        if (db != null && db.isOpen()) {
            db.close();
        }
    }

    private class RetrieveCursorTask extends AsyncTask<Void, Void, Cursor> {
        private Context ctx;

        public RetrieveCursorTask(Context ctx) {
            this.ctx = ctx;
        }

        @Override
        protected Cursor doInBackground(Void... params) {
            Cursor cursor = null;
            DbHelper helper = new DbHelper(ctx);

            try {
                db = helper.getReadableDatabase();
                cursor = db.query("users",
                    new String[] {
                        DbHelper.ID_COLUMN,
                        DbHelper.UID_COLUMN
                    }, 
                    null, null, null, null, null);
                startManagingCursor(cursor);
            } catch (Exception e) {
            }
            return cursor;
        }

        @Override
        protected void onPostExecute(Cursor cursor) {
            super.onPostExecute(cursor);

            if (cursor != null) {
                try {
                    adapter = new MyCursorAdapter(ctx, cursor);
                } catch (Exception e) {
                }
                setListAdapter(adapter);
            } 
        }
    }

    private class MyCursorAdapter extends CursorAdapter {
        private Context ctx;

        public MyCursorAdapter(Context context, Cursor c) {
            super(context, c);
            this.ctx = context;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // ...
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // ...
        }
    }
}
+3
source share
2 answers

Take a look at AsyncQueryHandler if you want to query DB the way you want.

RetrieveCursorTask , , , AsyncTask , , onDestroy, AsyncTask.

+4

, , onPostExecute. , AsyncTask , , , . .

    @Override
    protected void onPostExecute(Cursor cursor) {
        super.onPostExecute(cursor);

        synchronized(anyObject) {
        if (cursor != null) {
            try {
                adapter = new MyCursorAdapter(ctx, cursor);
            } catch (Exception e) {
            }
            setListAdapter(adapter);
        } 
        }
    }
0

All Articles