Exception: trying to get SQLiteClosable closing link

I sent this back in May to the Google developers group [android-developers]. I never heard back and could not reproduce the problem until one of my students did last week. I thought I posted it here and see if he calls any of the bells.

In one of my code samples, I have the following method:

static Cursor getAll(SQLiteDatabase db, String orderBy) { return(db.rawQuery("SELECT * FROM restaurants "+orderBy, null)); } 

When I run it, sporadically, I get the following:

 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): java.lang.IllegalStateException: attempt to acquire a reference on a close SQLiteClosable 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:31) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:56) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1092) 05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at apt.tutorial.Restaurant.getAll(Restaurant.java:14) 

It makes no sense to me. The database is definitely open. SQLiteClosable is SQLiteQuery created by SQLiteQueryDriver , and I see no evidence that there is a pool of objects or something is happening here that might explain how the β€œnew” SQLiteClosable already closed. the fact that it is sporadic (which means that the same user interface operations are sometimes performed to throw an exception, but not always) offers some kind of pool, race state or something ... but I don't know where.

Thoughts?

Thank!

UPDATE . This code applies to the LunchList tutorials from my Android Programming Tutorials book. It is slightly decomposed and not very suitable for publishing directly to SO. You can download the code for this book from the link above if you want to take a look at it. I don’t remember exactly which edition of the textbook the student was working on at that time, although he was in Tutorial 12-Tutorial 16. I basically hoped to run into someone who had stumbled on this problem before and had a probable culprit. I am sure my database is open. Thanks again!

+42
android
Sep 27 '09 at 14:02
source share
4 answers

It made me crazy for the longest time. The solution I found is pretty simple: do not keep references to SQLiteDatabase objects. Instead, use SQLiteOpenHelper and call getWritableDatabase() every time you need it. From the docs:

public synchronized SQLiteDatabase getWritableDatabase ()

Create and / or open the database that will be used for reading and writing. After a successful opening, the database is cached, so you can call this method every time you need to write to the database.

The answer was there all the time.

+50
Mar 20 '10 at 23:05
source share

SQLiteDatabase automatically closes under certain conditions.

http://darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed-automatically.html

The getCount () and onMove () cursor methods trigger the actual query using SQLiteQuery. After receiving all the necessary data, SQLiteQuery decreases the reference count of the instance of SQLiteDatabase. When the reference count reaches 0, the database closes.

Note that the query can be executed asynchronously, in which case getCount () can return -1 if it is called before SQLiteQuery completes the data preparation.

+8
Mar 12 '11 at 6:00
source share

I had the same problem for several days, and my solution was to put the open () method just before my query and close () method after the database operation. It looks something like this.

 open(); Cursor cur=db.query(DATABASE_TABLE_CON, null, null, null, null, null, " name ASC"); close(); return cur; 

This works fine, but I care about the cost of resources. I'm not sure that I spend more resources with all of these opening and closing databases before any action.

+1
Nov 04 '09 at 8:38
source share

I had a similar problem, despite the fact that after the advice of Jarett . In my case, the problem occurs quite regularly when the orientation changes. I found that for some reason I have not reached the end yet, my code generates two identical, rather simultaneous AsyncTasks when the orientation changes (unlike only one when the activity starts normally). These tasks simultaneously perform the same database query from different threads.

This exception (or sometimes some other SQLiteException) is the result. Thus, it seems that this message may be a symptom of concurrency problems, even if this is not necessarily the root of the original problem posted here.

+1
Sep 26 '10 at 0:51
source share



All Articles