3

I've Googled around and have found multiple ways of accessing a local SQLite database asynchronously:

  • AsyncTask
  • CursorLoader (I've already used this for a query to retrieve my contacts information, but I'm not sure how this will translate to a SQLiteOpenHelper subclass with multiple queries)
  • ContentProvider - Not sure if it's overkill, the database will only be need from within the app

What is the best practice? I currently have a SQLiteOpenHelper subclass which contains the basic table creation/upgrade/etc. logic.

2
  • Are you talking about read operations only (queries), or also write operations (insert, update, delete)? Commented Dec 17, 2015 at 4:22
  • Both read and write operations. Commented Dec 17, 2015 at 6:38

2 Answers 2

9

CursorLoader only supports queries. You may still want to use it and leverage the Loader framework if you are displaying data in your UI. CursorLoader is intended to be used with a ContentProvider, but you can instead copy the source code and modify it to take an SQLiteDatabase instead of a Context and query the database instead of a ContentResolver inside the loadInBackground() method.

For write operations, you have several options to consider (these are not mutually exclusive, you may end up using more than one depending on the situation):

  • AsyncTask
  • Handler
  • IntentService
  • AsyncQueryHandler
  • Java threading/executor framework

I typically use AsyncTask for one-off operations that may have minor UI implications (e.g. showing and hiding some indicator on screen). Note that AsyncTasks run serially on a single worker thread, unless you supply your own Executor to execute().

IntentService is useful in that it queues all of its start commands and executes them serially on a worker thread, and automatically shuts down when finished with all of them. It's a Service, so it runs separately from any Activities/UI components, but that also means there's some overhead since it is an application component that needs to be created and started by the system. I like them for batch operations or operations that are scheduled sometime in the future.

AsyncQueryHandler does more than just queries (despite how it's named), but like CursorLoader it expects you are communicating with a ContentProvider. You can use a single one to process different kinds of operations. It's important to note that ContentProvider by itself does not provide asynchronous processing, you have to call it from a background thread, which is what AsyncQueryHandler does.

Finally, good old Java threading and the executor framework works just fine, though you'll probably want to have some kind of application component for them to run in (likely a Service, but if that's the case you might just go with IntentService above anyway).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your response, I found it tremendously helpful. However, there is still something that is bothering me: AsyncQueryHandler does not appear to be capable of batch inserts. This is a bit of an issue for me, as I am wanting to insert a couple hundred records into the database. In that scenario, would getContentResolver().applyBatch be better suited for the job? (I am assuming this is going to run on the UI thread). Or should I just call startInsert via AsyncQueryHandler several hundred times? It seems like an IntentService Subclass might not be such a bad idea after all...
1
  • CursorLoader is only for read data asynchronously
  • ContentProvider is to provide data to others applications, there's no option for synchronously or asynchronously access.

I suggest you to use AsyncTask

3 Comments

This is not correct. ContentProvider can provide data to your own application as well.
@Karakuri please read the doc : developer.android.com/reference/android/content/… "A content provider is only required if you need to share data between multiple applications."
I have built at least half a dozen apps that used a ContentProvider, most of them did not share data with other apps. Just because it isn't required does not mean you can't use one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.