Question

What is the "Android way" to implement a database framework?

The two goals:

  1. It should be generic enough so that the "database" can be a sqlite database or something over the network.
  2. It should be multi-thread safe. (Updated: By "thread safe", I mean it should NOT run in the main UI thread, database calls should not conflict with each other, and the system should know how to communicate results back to the main UI thread.)
  3. Updated: It should know about configuration changes (like changing the phone orientation)

This is what I've gathered from here and the Android docs:

  1. Use a LoaderManager for querying data.
  2. Create a ContentProvider (1 & 2 makes it thread safe)
  3. Put an extra class between the ContentProvider and the data.

However, what about creating, updating, and deleting data? As far as I can tell, the LoaderManager is just for queries. Should I be using an AsyncQueryHandler?

Update: an AsyncQueryHandler doesn't know about configuration changes. I've read that Fragments may be the way to go. Or... I'll have to make sure my AsyncQueryHandler implementation handles configuration changes.

Was it helpful?

Solution

(1) is pretty easy: just put an extra class between the ContentProvider and the data that implements all the low-level CRUD. For example, one class can handle sqlite databases and another class with the same interface can handle a Google drive backend.

After doing some research, here's how you can handle (2) and (3) with Android classes:

  • AsyncTask - unfortunately, AsyncTask doesn't know about configuration changes, so you have to write that yourself (and it gets ugly).
  • headless fragments - Fragments without a UI. You basically have to write your own AsyncTaskLoader so that defeats the point. (See here http://blogactivity.wordpress.com/2011/09/01/proper-use-of-asynctask/)
  • AsyncTaskLoader - seems to be the way to go

Loaders are designed to load data but you can hack a Loader to also handle insertions/update. (You can do whatever you want in the loadInBackground() method.)

The catch is that before HoneyComb, all Loaders share a thread pool to excecute requests in parallel. (After HoneyComb, Loaders execute tasks in sequence.) This means that not only are tasks that execute immediately after each other NOT guaranteed to execute in order but there will be data consistency issues if you don't handle multi-threading correctly.

If you have a Service running in the background that updates the database, you'll still have to worry about multi-threading in post-Honeycomb.

The bottom line is that there doesn't seem to be Android framework that abstracts away the problem of "database calls should not conflict with each other". You have to handle that on your own.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top