Android SQLite SQLiteOpenHelper IllegalStateException - DB Already Closed Error Android SQLite SQLiteOpenHelper IllegalStateException - DB Already Closed Error sqlite sqlite

Android SQLite SQLiteOpenHelper IllegalStateException - DB Already Closed Error


Since this question has gotten a good deal of attention, I wanted to answer it and describe what I've learned and what worked for me to correct this problem in my large, database-driven application:

  1. Do NOT use managed cursors. There's a reason why they're deprecated. They're completely problematic. Realistically, there's very few scenarios where you actually need to use a managed cursor anyway. Instead, run your query and populate an object with the results. If you're querying for multiple row, create an ArrayList<> of your object to hold all the rows. What I do now is create a function that runs the query and passes me back my ArrayList<> rather than a cursor in the return. I close the cursor within the function and I'm done. For a ListViews, you'll no longer be able to use a SimpleCursorAdapter. Just convert all of these to a BaseAdapter and use your ArrayList<> object to populate it.

  2. DO NOT FORGET TO CLOSE ALL YOUR CURSORS. This can also wreak havoc on your app's db connections. I thought I was doing this but, sure enough, found a spot that I wasn't explicitly closing a cursor. So, go through your app and double check all of them.

I'm also using a singleton DatabaseHelper object. I declare a static DatabaseHelper object within my SQLiteOpenHelper class so that I'm getting the same instance every time.

I now have a stable running app that no longer gets these DB errors. I hope this information is helpful to some of you.


use CursorAdapter.changeCursor(null) ,Can slow the emergence of this bug,But can not completely solve the problom ,Unknown period of time will appear again. This has been driving me crazy too!


I had also the same problem 'db already closed exception with a cursor invalid statement in fillWindow() and IllegalStatementException'. What I did was I put my cursor (w/c also comes from SimpleCursorAdapter) to an instance variable instead of a method variable then on my onStop and onPause methods I call stopManagingCursor then on my onResume and onStart methods I call startManagingCursor.

It solved my problem for me and I didn't find any error or warning messages in my logcat after that :) Hope this helps anyone also.