Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is SQL or general file access appropriate in the Android main UI thread?

I'm trying to follow Android best practices, so in debug mode I turn all the following on:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all thread violations
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all virtual machine violations

Android now yells at me when I try to use any sort of file access or SQL in the main (UI) thread. But I see so many recommendations to use file access and/or SQL in the main thread. For example, the main activity should load default preference values inside onCreate() in case they haven't been set yet:

PreferenceManager.setDefaultValues(context, resId, readAgain);

Oops---that results in a file access on the first application execution, because onCreate() is called on the UI thread. The only way around it I can see is to start a separate thread---which introduces a race condition with other UI code that might read the preferences and expect the default values to already be set.

Think also of services such as the DownloadManager. (Actually, it's so buggy that it's useless in real life, but let's pretend it works for a second.) If you queue up a download, you get an event (on the main thread) telling you a download has finished. To actually get information about that download (it only gives you a download ID), you have to query the DownloadManager---which involves a cursor, giving you an error if you have a strict policy turned on.

So what's the story---is it fine to access cursors in the main thread? Or is it a bad thing, and half the Android development team and Android book authors forgot about that?

like image 886
Garret Wilson Avatar asked Nov 30 '11 00:11

Garret Wilson


People also ask

What is main UI thread in Android?

User Interface Thread or UI-Thread in Android is a Thread element responsible for updating the layout elements of the application implicitly or explicitly. This means, to update an element or change its attributes in the application layout ie the front-end of the application, one can make use of the UI-Thread.

Which action should be performed on the main thread Android?

The main thread is responsible for dispatching events to the appropriate user interface widgets as well as communicating with components from the Android UI toolkit. To keep your application responsive, it is essential to avoid using the main thread to perform any operation that may end up keeping it blocked.

What are the main two type of thread in Android?

There're 3 types of thread: Main thread, UI thread and Worker thread. Main thread: when an application is launched, the system creates a thread of execution for the application, called main.

What is difference between main thread and UI in Android?

Originally Answered: What is difference between UI thread and main thread in Android? UI thread is what render UI component/Views. Main thread is what which start the process/app. In Android UI thread is main thread.


1 Answers

The only way around it I can see is to start a separate thread---which introduces a race condition with other UI code that might read the preferences and expect the default values to already be set.

Then use an AsyncTask, putting the setDefaultValues() call in doInBackground() and the "other UI code that might read the preferences" in onPostExecute().

To actually get information about that download (it only gives you a download ID), you have to query the DownloadManager---which involves a cursor, giving you an error if you have a strict policy turned on.

So query the DownloadManager in a background thread.

So what's the story---is it fine to access cursors in the main thread?

That depends on your definition of "fine".

On Android 1.x and most 2.x devices, the filesystem used is YAFFS2, which basically serializes all disk access across all processes. The net effect is that while your code may appear sufficiently performant in isolation, it appears sluggish at times in production because of other things going on in the background (e.g., downloading new email).

While this is a bit less of an issue in Android 3.x and above (they switched to ext4), there's no question that flash I/O is still relatively slow -- it will just be a bit more predictably slow.

StrictMode is designed to point out where sluggishness may occur. It is up to you to determine which are benign and which are not. In an ideal world, you'd clean up them all; in an ideal world, I'd have hair.

Or is it a bad thing, and half the Android development team and Android book authors forgot about that?

It's always been a "bad thing".

I cannot speak for "half the Android development team". I presume that, early on, they expected developers to apply their existing development expertise to detect sluggish behavior -- this is not significantly different than performance issues in any other platform. Over time, they have been offering more patterns to steer developers in a positive path (e.g., the Loader framework), in addition to system-level changes (e.g., YAFFS2->ext4) to make this less of a problem. In part, they are trying to address places where Android introduces distinct performance-related challenges, such as the single-threaded UI.

Similarly, I cannot speak for all Android book authors. I certainly didn't focus on performance issues in early editions of my books, as I was focusing on Android features and functions. Over time, I have added more advice in these areas. I have also contributed open source code related to these topics. In 2012, I'll be making massive revisions to my books, and creating more open source projects, to continue addressing these issues. I suspect, given your tone, that I (and probably others) are complete failures in your eyes in this regard, and you are certainly welcome to your opinion.

like image 82
CommonsWare Avatar answered Sep 20 '22 04:09

CommonsWare