You should close SQLiteDatabase objects in Android developing (1)


Close “SQLiteDatabase” properly and reliably

I have developed an Android application that uses SQLite and checked the log after leaving it for a while to run. Then I found warnings in logs below.

W/SQLiteConnectionPool(1261): A SQLiteConnection object for database ‘/data/data/…..’ was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

Unfortunately, it is not mentioned in particlular Storage Options | Android Developers that you should close database objects.

So, I looked at the source code of Android and studied how properly and reliably you shoud close “SQLiteDatabase” objects. I will describe below.

Looking at the source code, “SQLiteDabase” object is managing the internal reference counter. So, even if you would call “close()” of the object, the object will not call “close()” of inner native code on its own side as long as the counter is not 0.

Therefore, for one “SQLiteDatabase” object, it is important to call “close()” of the appropriate number of times. Perhaps exceptions is thrown if you call it much times. And objects are leaked if you call it less times.

3 Patterns to close “SQLiteDatabase”

I think it is a good idea to follow the following principles.

[Pattern 1]
Get the object at the time of use and close it when you have finished to use it.
This is the most simple and safe way. With “try” – “finally”, you can execute “close()” for sure.

[Pattern 2]
Keep the “SQLiteDatabase” object to an instance field and call “close()” only once at the end.
If you concern the cost to obtain the object eatch time, this method would be good. In the “Service” or “Activity”, you should call “close()” in “onDestroy()”.

[Pattern 3]
If you pass a “SQLiteDatabase” object to the other thread, you should call “acquireReference()” method in the original thread and call “close()” in the new thread.

Because “acquireReference()” method increments the reference counter, you must call “close()” one extra. If you call “close()” in both the original thread and new thread, actual “close()” is performed. There is no problem if you call “close()” in any order.

In this way, in using the “SQLiteDatabase”, if you call “close()” when they are no longer needed, you can avoid the leak.

In addition, “Cursor” objects, which is used to perform query, also should be closed. But I don’t think you should pass them to another thread because there is no method that corresponds to “aquireReference()” of them.

[Reference Site]
You should close SQLiteDatabase in Android developing (2) | DeVlog


Your email address will not be published.