I believe the message you're referring to is not a race condition, but
rather is detecting the problem when the GC finds the DB connection
freeable, but still open.
You should be sure to call close() on the returned DB before releasing
the last reference to it. For example:
SQLiteDatabase db = mySQLiteOpenHelper.getReadableDatabase();
try {
db.execSQL(...);
} finally {
db.close();
}
This is a pattern that should be ingrained into everyone's brain for
all closeable things -- files, database connections, statements,
cursors, network connections... And one try/finally for EACH ONE,
please -- don't try to do cleanup for several all in the same finally
clause, or if a later open/create fails, you'll leak the earlier ones.
Things are a bit more complicated if they must exist over a longer
period of time in a field of an object. It's best to avoid doing that,
but if it's necessary, you need to very carefully consider the
object's lifetime, and make sure to close the closable object before
the object can be potentially freed.
On Oct 18, 11:15 pm, William Ferguson <[email protected]>
wrote:
> I'm not doing anything re locking the DB, so I would imagine I would
> be getting default behaviour.
>
> But if one of Activities does:
> db = mySQLiteOpenHelper.getReadableDatabase();
> db.exexSQL(...) or db.query(...)
>
> and the IntentService does the following BEFORE the code above has
> managed to close the DB
> db2 = mySQLiteOpenHelper2.getWritableDatabase();
> db2.exexSQL(...) or db.query(...)
>
> then a stacktrace is written in the logs indicating that the
> ReadableDatabase resources were not closed when they should have been.
> So then seems to be some kind of resource conflict caused by the race
> condition. And I'd like to avoid that.
>
> And I didn't understand your example that you suggests improves
> performance.
> It looks like you are just replacing the value of a local cursor
> variable with a newly constructed cursor each time.
> It doesn't appear that you are reusing the cursor in any way.
> Unless someDbAccessMethod(); is always returning the same cursor ??
> But that doesn't make sense because
> a) it would be returning the cursor you just closed, so its no longer
> any good to you.
> b) the cursor would always return the same dataset, so I can't see how
> its that useful.
>
> But maybe I'm way off mark ..
>
> On Oct 19, 2:05 pm, Bret Foreman <[email protected]> wrote:
>
>
>
> > SQLite has locking on by default and you can have any number of
> > threads accessing it concurrently if you leave it in locking mode.
> > Opening and closing the database and/or the cursors is not especially
> > expensive. One trick that improves performance is to re-use the cursor
> > after you close it so the object doesn't have to be rebuilt. Something
> > like this:
>
> > // cursor used here
>
> > // Now finished with cursor
> > theCursor.close();
> > theCursor = someDbAccessMethod();
> > // More work with new cursor
>
> > For example, I might have 5 or 6 methods in a given Activity that all
> > re-use the same cursor as long as I'm sure my logic does not require
> > two of them to use the cursor at the same time. Then the cursor object
> > is only created in onCreate.
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en