Do you feel envy when you see how fast and smooth iPhone apps are?
Do you want your own apps to run smoothly even on low-end devices?
Are you afraid that making your app faster requires a lot of time and knowledge?
Making your Android apps faster is easy, but there is not much information out there.
Why apps feel slow and unresponsive?
Each Android app has at least one thread where its code is running. It’s called the UI thread because it handles all drawings on the screen and user interactions. Each time a text is shown, or an activity displayed, it’s on the UI thread. Each time a user taps on the screen, the UI thread identifies what and where was touched and call the appropriate functions.
What happens if other code runs on the UI thread?
The thread will have less time to draw on the screen and respond to the user, and the app will feel slow and sluggish.
When and where is code running on the UI thread?
The short answer is always. When a button is tapped the callback is executed on the UI thread. The activity life-cycle with onCreate, onStart and their friends run on the UI thread. Even the onReceive of a BroadcastReceiver runs on the UI thread.
How to make an app feel faster?
The solution is simple. Don’t do anything on the UI thread. In fact, you will have to interact with UI components, like TextViews, only on the UI thread. This is a limit imposed by the Android OS. Besides that all other code has no reason at all to be there.
I know what many of you are thinking: we should launch other threads, but managing them is hard and error prone, and that is why we don’t do it.
You are right. Managing threads is hard and error prone, and that is why we won’t do it.
There are two very nice and simple classes that will do it for us.
They are called IntentService and AsyncTask.
Simple implementation of IntentService:
To start it from your activity:
How hard was it? All the code in the onHandleIntent is run on a separate thread which is managed entirely by the IntentService class.
You can only pass very little and simple information trough intents. However you can read data from files and databases.
IntentService has also other great features. At any single time it process exactly one Intent. If you send several intents simultaneously it will handle them one by one. This is great for things like synchronizing with a web service. Another great feature is that even when you app is closed, Intent service continues to work until it finishes what it has to do.
How do you notify the user of what is happening in an intent service? The best way is to use NotificationManager. You can show notifications in the status bar as well as progress.
If you need to notify your own code it is also very simple. When you launch an activity you should register local BroadcastReceiver to listen for specific actions. Then in the intent service you send a broadcast with sendBroadcast(intent).
A simple implementation of AsyncTask:
To run this task:
How hard was it? Whenever you call execute a new thread will be started to execute the task in the doInBackground method.
AsyncTask will be killed when you app closes. Therefore it is not good for long running tasks like synchronizing and downloading or heavy processing. For such tasks use IntentService.
However AsyncTask is great for small simple tasks and you can easily pass complex classes with data. For example, when storing data in a database.
AsyncTask has one more great method.
The result which is returned from doInBackground (the 2+3 above), is passed to onPostExecute. The onPostExecute is then executed on the UI thread. The pattern is then: you do your job on the doInBackground, then once ready you pass the result to onPostExecute to show it to the user. Very simple isn’t it?
In everything above you never ever manage or think about threads, all the hard work is done for you by those two classes. Use them a lot and your apps will be blazingly fast.
How fast can it be?
The new versions of Tasks will be released in a few weeks. It uses everywhere AsyncTasks and IntentServices, nothing is done on the UI thread besides setting the values of the views. Tasks runs super fast even on low-end phones made 2 years ago, like the first version of HTC wildfire! It synchronizes with servers, writes a lot of database stuff and still is super fast and fluid. Most importantly it was very easy and natural to implement it with AsyncTasks and IntentServices.