logo

UI Thread and Background Processing

Android modifies the user interface via one thread, the UI Thread. If the programmer does not use any concurrency constructs, all code of an Android application runs in this UI thread. If you perform a long lasting operation the user interface of your Android Application will block until your code has finished.

Therefore all

potentially slow running operations in an Android application should run in the background, e.g. via some way of concurrency constructs of the Java language or the Android framework. Potential slow operations are network, file and database access but also complex calculations.

This tutorial will teach how to use the special Android constructs for concurrency.

Background Processing using Threads & Handlers

Threads

Android supports standard Java Threads. You can use standard Threads and the tools from the package “java.util.concurrent” to put actions into the background. The only limitation is that you cannot directly update the UI from the a background process.

If you need to update the UI from a background task you need to use some Android specific classes. You can use the class “android.os.Handler” for this or the class “AsyncTasks

Handler

The class “Handler” can update the UI. A handle provides methods for receiving messages and for runnables. To use a handler you have to subclass it and override handleMessage() to process messages. To process runables you can use the method post(); You only need one instance of a handler in your activity.

You thread can post messages via the method sendMessage(Message msg) or sendEmptyMessage.

Sample Example

Here in this example we will notify user when for example user click button and in onClick method program starts some long-time process which will do your task in background with the help Handlers.

So create a project named “com.mobisys.android.handler_ex” having “HandlerActivity” in it.

main.xml contains:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >
    
	<Button  
	   android:layout_width="wrap_content" 
	   android:layout_height="wrap_content"
	    
	   android:text="Get Message"
	   android:id="@+id/button01"/>
        
    <TextView android:id="@+id/text01"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginTop="4dp"
       android:text="Message return from handler">
     </TextView>
</LinearLayout>

So, let us take the handler from the main thread and see how we can use it to communicate with a child thread.

When a handler is created, it is associated by default with the current thread.
First we need to to override handleMessage() method.

Handler messageHandler = new Handler() {
    	
    	@Override
    	public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle b1=msg.getData();
            
            txt.setText(b1.getString("message"));
            progressDialog.dismiss();
            
            }     

    	
    };

At second we need to create Thread.

new Thread() {

public void run() {

//long time method

handler.sendMessage(Message);

}

}.start();

on click of the button, the runInBackground() method is invoked. Assuming that this is a very time consuming task, we will start a thread and do the task and return from that thread as shown in the code below:

((Button)findViewById(R.id.button01)).setOnClickListener(new View.OnClickListener(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				
				runInBackground();
				
			}
        	
        });

protected void runInBackground() {


        progressDialog = ProgressDialog.show(this, "", "Doing...");


        new Thread() {


            public void run() {
//Implementing your long running operations
            try {
                Thread.sleep(1000);                  
                } catch (InterruptedException e) {
            }
                Message m=Message.obtain();
                prepareMessage(m);
                
                messageHandler.sendMessage(m);
            }
         }.start();
       
    }
    public void prepareMessage(Message m)
    {
       Bundle b = new Bundle();
       b.putString("message", "Activity Done in background!!!!!!!");
       m.setData(b);
       
    }

Since it is time consuming, We are starting a ProgressDialog just to inform the end user that some activity is happening. Then, we start the thread, make it sleep for 1000 milliseconds and send back message through the message handler. The messageHandler.sendMessage(m) is the callback on the parent thread’s messageHandler to inform that the child thread has finished its work or you can also send empty message through the messagehandler. i.e messageHandler.sendEmptyMessage(0)

Now the control returns to handleMessage() call back method & sets the message to TextView.That method shown in the beginning just dismisses the progressDialog.

Background Processing using AsyncTask

If you have an Activity which needs to download content or perform operations that can be done in the background AsyncTask allows you to maintain a responsive user interface and publish progress for those operations to the user.

Create your inner class which extends AsyncTask< String, void, String> & implements
4 methods:
1) doInBackground: Code performing long running operation goes in this method. When onClick method is executed on click of button, it calls execute method which accepts parameters and automatically calls doInBackground method with the parameters passed.

2) onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.

3) onPreExecute: This method is called before doInBackground method is called.

4) onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.

Sample Example

We will have a exercise of a Horizontal ProgressBar which running in a background AsyncTask.

So create a project named “com.mobisys.android.ex_asyncTask22” having activity “AndroidAsyncTaskProgressBar” in it.

main.xml contains:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 >

<Button
 android:id="@+id/startprogress"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Start"
 />
<ProgressBar
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:layout_marginTop="8dp"
 style="?android:attr/progressBarStyleHorizontal"
 android:id="@+id/progressbar_Horizontal"
 android:max="100"
 />
</LinearLayout>

then Activity AndroidAsyncTaskProgressBar will look like:

package com.mobisys.android.ex_asyncTask22;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

public class AndroidAsyncTaskProgressBar extends Activity {

ProgressBar progressBar;

public class BackgroundAsyncTask extends
AsyncTask {

int myProgress;

@Override
protected void onPostExecute(Void result) {

Toast.makeText(AndroidAsyncTaskProgressBar.this,
“onPostExecute”, Toast.LENGTH_LONG).show();

}

@Override
protected void onPreExecute() {

Toast.makeText(AndroidAsyncTaskProgressBar.this,
“onPreExecute”, Toast.LENGTH_LONG).show();
myProgress = 0;
}

@Override
protected Void doInBackground(Void… params) {

while(myProgress<100){ myProgress++; publishProgress(myProgress); SystemClock.sleep(100); } return null; } @Override protected void onProgressUpdate(Integer... values) { progressBar.setProgress(values[]); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); progressBar = (ProgressBar)findViewById(R.id.progressbar_Horizontal); progressBar.setProgress(0); ((Button)findViewById(R.id.startprogress)).setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { new BackgroundAsyncTask().execute(); } }); } } [/sourcecode]

Run
the application

Download Sourcecode

Click here to download source code.

AUTHOR: Vikas Hiran
3 Comments
  • amir

    hi, btw great tutorial, actually i want this, when we click start the prograss bar in running and when we click back and close the app the process is still running but the prograss bar is empty, can we capture what is running in the back ground and when the user clicks on the app and enters in the app the progross bar is still running and not empty

    Thankx

    January 15, 2012
  • Yes, you can do that ofcourse. Background thread will do downloading and it will track the progress of the download in some public static variable.. So next time whenever you start the activity with progress bar, you just need to set the progress of the progressbar to the progress value stored in public static variable..

    January 15, 2012
  • amir

    Thankx buddy, it worked

    January 15, 2012

Leave a Comment

Your email address will not be published.