In my application I need a lot of CRUD stuffs: read records from the local SQLite database, insert objects and updating stuffs. Most of the queries are so simple that they won't block even if run on the UI thread, however in this application I want to adopt the Windows Phone pattern: an out animation started immediatelty and an in animation started when the result is delivered.
I planned to use an AsyncTask
for the job, however I noticed that Honeycomb (and the compat package) introduces this new Loader framework. The main advantage seems that data loaded by a Loader
survive config changes. The LoaderEx project by Commonsware bridges between SQLite and the framework, but some problems arise.
Resources cleanup: I use a single activity, create the SQLiteOpenHelper in onCreate()
and close it onDestroy()
. Since the loader manager may still be running, i check it and set a pendingClose
flag on my callbacks object, so it will close the cursor and the helper when load finishes. I think not closing the database is not harmful, but SQLite complains if you don't do it, and I don't like error messages :) The point here is that data doesn't survive config changes, so the Loader advantage vanishes
How many loaders should I create? Let's say I have the beloved Customer
and Order
tables. Loaders are identified by ID
's like CUST_L
or ORD_L
, but every time the user clicks on some summary I want to bring in a screen with the detail. Should I restart
a loader with different params, or should I init
a new one with a random ID? This may happen dozens of times. Is the Loader framework intended for lots of small running jobs, or just for a few long running tasks?
What's the purpose of using ID
's inside the LoaderCallbacks
interface? Why not a simple initLoader(params, callback)
? I don't think one can reuse some piece of logic inside a callback: eventually he will branch (with if-else
or switch
on ID) so I don't understand the point of giving an identifier to the callbacks object, instead of a naive approach one-callbacks-per-operation.
I'm asking this because the whole framework seems overengineered to me and without real utility. I don't understand the point of centralizing code with a LoaderManager
, and I can't see any new opportunity AsyncTask
did not offer.
The only win point is config changes survival, but I can't exploit it because of resources cleanup, and I can't figure out an alternative way to close the SQLiteOpenHelper
because (quite obviously) the SQLiteCursorLoader
requires it but clean it up is up to the user. So AsyncTask
seems the winner choice here, but maybe I'm missing something.
My experience shows that even though using Content Providers sounds like overkill to implement, it actually pays off pretty good in the future. Performance hit is insignificant (tried measuring it), UI-Data bindings are added out of the box (because of content observer and CursorLoaders being able to subscribe to Uri notifications), synchronicity implemented by framework via loaders. IMHO, whenever database is needed, using content provider with loaders most of the times is the best solution you can come up with.
Other scenarios that involve using database directly, will force you to implement everything manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With