Closing an SQLite database on one thread breaks the database opened on another thread
We all learn that resources, such as database connections, should be acquired late and released early.
Yet applying this principle to SQLite database connections on Android have caused me some headache.
I have an app that download updates from a backend server in a service working in the background, writing updates to the database at a regular basis. The problem I experience arise when the following sequence occurs:
- Service opens a writable database connection
- Some activity opens a readable database connection
- Service closes its database connection concurrently with the activity reading data
- Activity fails due to its database connection was closed
Both the service and the activity uses the same SQLiteOpenHelper
class, though different instances, to open their connections. My initial assumption was that this should work just fine, but somehow it seems that the underlying connection is shared between the two database instances.
To work around the problem I ended up not closing the database objects, only closing any opened cursors. This seems to work, though I'm not sure that I'm not leaking memory here.
Is 开发者_开发技巧there something obvious I am missing here?
Is there something obvious I am missing here?
I'd say no. Looking at the source code to SQLiteOpenHelper
, I can't see how two instances could be sharing a SQLiteDatabase
object.
Some diagnostic suggestions:
- Dump the
toString()
value of eachSQLiteDatabase
, which should give you a Java instance ID. If they are the same, that is where your problem lies, and you will need to work your way upstream to figure out how the heck this is happening (e.g., you really are using the same instance of theSQLiteOpenHelper
). - With your database in a stable state (i.e., no need to create or upgrade), flip one of your two database spots to use
SQLiteDatabase
directly, rather than viaSQLiteOpenHelper
, and see if that changes matters.
精彩评论