Home > Android > Android:Update UI through handler

Android:Update UI through handler

Here is a short memo for Handler class I have used in my recent project.

Class Overview

A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it — from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler’s handleMessage(Message) method (requiring that you implement a subclass of Handler).

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.

When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler’s message queue and processed when appropriate.

A Handler can send both Message and Runable objects.

Layout


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

<TextView
android:id="@+id/txtView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_weight="1"
android:background="#969696"
android:textColor="#fff"
android:textSize="29sp" />

<Button
android:id="@+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Handle in Android" />

</LinearLayout>

  • Message

public class MainActivity extends Activity {

private int index = 0;

private Button btnTest;
private TextView txtView;

private final Handler handler = new Handler() {
public void handleMessage(Message msg) {

txtView.setText(index++ + "");
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

txtView = (TextView) findViewById(R.id.txtView);
txtView.setText(index++ + "");

btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
public void run() {
try {
Thread.sleep(1000);

Message msg = handler.obtainMessage();
handler.sendMessage(msg);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
});
}
}

  • Runable

public class MainActivity extends Activity {

private int index = 0;

private Button btnTest;
private TextView txtView;

private final Handler handler = new Handler();

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

txtView = (TextView) findViewById(R.id.txtView);
txtView.setText(index++ + "");

btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(new Runnable() {

@Override
public void run() {

txtView.setText(index++ + "");
}
});
}
});
}
}

Having the Handler final and declaring it in the class definition is a good practice.

A sample for progress bar , using both runnable and message.

Layout


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

<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progress="0"
android:visibility="gone" />

<Button
android:id="@+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Handle in Android" />

</LinearLayout>

Java


public class MainActivity extends Activity {

private Button btnTest;
ProgressBar progressBar;

private final Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
progressBar.setProgress(msg.arg1);
handler.postDelayed(run, 1000);
}
};

private final Runnable run = new Runnable() {

int index = 0;

@Override
public void run() {

index += 10;
Message msg = handler.obtainMessage();
msg.arg1 = index;

handler.sendMessage(msg);
if (index >= 100)
handler.removeCallbacks(this);
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

progressBar = (ProgressBar) findViewById(R.id.progressBar);

btnTest = (Button) findViewById(R.id.btnTest);
btnTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressBar.setProgress(0);
progressBar.setVisibility(View.VISIBLE);
handler.post(run);
}
});
}
}

Advertisements
Categories: Android

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: