Is it good practice to re-use a cursor object in android to make multiple queries on a database? Do I need to call deactivate() between queries? I am deactivating the cursor after the second query but I am still getting DatabaseObjectNotClosedException开发者_运维问答 warnings in logcat.
Both requery()
and deactivate()
has been deprecated now (the first one since API 11, the latter since API 16). I'm answering this almost 7 years old question because I believe there's not a correct answer given yet.
In my experience, re-using a Cursor
object is a bad practice. My implementation of SQLiteOpenHelper
class has several methods, and I close the Cursor
object in all of those - and I believed that since I closed the Cursor
object at the end of each method, it was correct. But in some methods I was re-using one Cursor
object for saving results from multiple queries to it (first I ran a query, then I read and used the result from the Cursor
, and then I ran a different query which I thought would simply overwrite the old result in an already used Cursor
). Enabling StrictMode
proved me wrong. I started getting DatabaseObjectNotClosedException
crashes.
I fixed it by not re-using the Cursor
object anymore. Now I create a new Cursor
variable for each query, then read and save the results, and the I call close()
method on the Cursor
and don't use it anymore. If I need to run another query in that method, I deliberately don't use the old Cursor
anymore, and I always create a new variable. I'm not getting any more warnings or crashes even when StrictMode
is enabled. I believe that garbage collector does it's job correctly, so I don't think that creating multiple instances of Cursor
class is a huge issue. Re-using only one Cursor
object, on the other hand, like an issue seems - hence your warnings and my crashes with StrictMode
.
I'm not a database expert and I'm still learning best practices in Android programming, but I believe that on this topic I'm correct - don't re-use Cursor
objects, or you can start getting memory leaks, warnings and possibly even crashes.
In my experience, you can just set the cursor to something new. I've tried calling deactivate() on it, but that messed up my app, so I decided not to use that. I don't know if it's good practice or not, but it worked fine for me and as far as my testing goes, it doesn't seem to leak or slow down anything.
Well, requery()
has been deprecated, bur for some reason deactivate()
is not. You can't really use one without the other, so I guess you could assume you shouldn't use deactivate()
. In any case, closing a cursor as soon as you are done with it will get rid of all those pesky DatabaseObjectNotClosedException
's. The new loader framework encourages returning new cursors, old ones are automatically closed when you replace them.
精彩评论