You are on page 1of 16

Android Threads

Process & Thread


• Process: is a running/executing program or an
executing instance of an application
• Thread: basic unit to which OS allocates processing
time
• A thread runs in the context of a process, a process
runs in the context of itself
• A thread is managed by either process or operating
system itself
• Processes have separate Address Space while
threads share the same address space
Threads in Android
• Application Components: Activity, Service, Receiver, Provider

• When an application component starts, Android OS starts a Linux


process for the application with a single thread of execution
called ‘main’

• If an application component starts and there already exists a


process for that application (because another component from
the application exists), then the component is started within that
process and uses the same thread of execution

• Normally all applications components run in the same process


but we control that too in the manifest using android:process
attribute in each component

• The <application> element also supports an


android:process attribute
Main Thread
• The main thread is in charge of dispatching events
to the appropriate user interfaces.

• All components are fired from the main thread

• Long running requests that can make the UI block


cannot be part of UI Thread, e.g. Network call or
database queries sometimes.

• Doing so results in ANR (Application not responding)


dialog which asks to quit the application.
Rules for UI Manipulation
• The Android UI toolkit is NOT thread-safe. So UI
shouldn’t be manipulated from any worker thread.
All manipulations should be made from UI Thread.

Rules:

1. Do not block the UI thread

2. Do not access the Android UI toolkit from outside


the UI thread
UI Manipulation
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}

• This seems fine and works fine as it creates a new


thread but it violates the second rule of UI
Manipulation which can cause trouble.
The Fix
• To fix this problem, Android offers several ways to
access the UI thread from other threads. Here is a
list of methods that can help:

• Activity.runOnUiThread(Runnable)
• View.post(Runnable)
• View.postDelayed(Runnable, long)
runOnUiThread
• Runs the specified action on the UI thread. If the
current thread is the UI thread, then the action is
executed immediately. If the current thread is not
the UI thread, the action is posted to the event
queue of the UI thread.

• runOnUiThread(new Runnable() {
@Override
public void run() {
videoView.start();
}
});
View.post(Runable)
• Causes the Runnable to be added to the message
queue. The runnable will be run on the UI thread.
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap b = loadImageFromNetwork("http://example.com/image.png");

mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}

• Now this implementation is thread-safe: the network


operation is done from a separate thread while the
ImageView is manipulated from the UI thread.
View.postDelayed
• public boolean postDelayed (Runnable action, long delayMillis)

• Same as View.post(Runnable) but causes the


Runnable to be run after the specified amount of
time elapses
Growing Complexity
• As the complexity of the operation grows, this kind
of code can get complicated and difficult to
maintain. Perhaps the best solution is to extend
the AsyncTask class, which simplifies the execution
of worker thread tasks that need to interact with the
UI.
AsyncTask
• AsyncTask allows you to perform asynchronous work
on your user interface. It performs the blocking
operations in a worker thread and then publishes
the results on the UI thread, without requiring you to
handle threads or handlers yourself.
Using AsyncTask
• Extend AsyncTask
• Implement the doInBackground() callback method.
• To update UI, implement onPostExecute()
• onPostExecute takes result
from doInBackground() and runs in the UI thread,
and safely update the UI
• Run the task by calling execute() from the UI thread
AsynTask Example
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {

protected Bitmap doInBackground(String... urls) {


return loadImageFromNetwork(urls[0]);
}

protected void onPostExecute(Bitmap result) {


mImageView.setImageBitmap(result);
}
}

• The system calls doInBackground to perform work in a worker


thread and delivers it the parameters given to
AsyncTask.execute()

• The system calls onPostExecute to perform work in the UI


thread
Misconceptions &
Problems with AsyncTask
• No visible change when Rotated
• The only way that an AsyncTask finishes early is if it is
canceled via AsyncTask.cancel()
• AsyncTask.cancel() does not kill the Thread with no
regard for the consequences! All it does is set the
AsyncTask to a “cancelled” state.
• Maximum Concurrent AsyncTasks: 128, (App
crashes onwards)
• Tip: Don’t use for long running background tasks
References
• http://developer.android.com/guide/components/processes-and-threads.html
• http://developer.android.com/reference/android/os/AsyncTask.html
• http://blog.danlew.net/2014/06/21/the-hidden-pitfalls-of-asynctask/
• http://developer.android.com/reference/android/view/View.html
• http://developer.android.com/reference/android/app/Activity.html

You might also like