Thursday, September 8, 2011

Use Handler and Runnable to generate a periodic event

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.



It's a example using Handler and Runnable to generate a periodic event in 500ms.



Use Handler and Runnable to generate a periodic event



package com.exercise.AndroidHandlerRunnable;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class AndroidHandlerRunnableActivity extends Activity {

private int cnt = 0;
Button Start, Stop;
TextView counter;
private Handler handler = new Handler();

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
counter = (TextView)findViewById(R.id.counter);
Start = (Button)findViewById(R.id.Start);
Start.setEnabled(true);
Stop = (Button)findViewById(R.id.Stop);
Stop.setEnabled(false);

Start.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.post(timedTask);
Start.setEnabled(false);
Stop.setEnabled(true);
}});

Stop.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler.removeCallbacks(timedTask);
Start.setEnabled(true);
Stop.setEnabled(false);
}});
}

private Runnable timedTask = new Runnable(){

@Override
public void run() {
// TODO Auto-generated method stub
cnt++;
counter.setText(String.valueOf(cnt));
handler.postDelayed(timedTask, 500);
}};
}





<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/Start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
/>
<Button
android:id="@+id/Stop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Stop"
/>
<TextView
android:id="@+id/counter"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>




5 comments:

unbrokenrabbit said...

Thanks for the example! I ran your code and discovered something that might be worth sharing with others who may have gotten the same impression as me on the first read through. Since the handler is created in the context of the main UI thread, every Runnable that gets posted to the handler also gets executed within the context of the main UI thread. So this is essentially a single-threaded example. When I first read your post, I mistakenly interpreted the "to enqueue an action to be performed on a different thread than your own" line to imply that there were multiple threads at work in this example. If there are others out there who made the same mistake, it might be helpful to clarify this point.

Erik said...

hello unbrokenrabbit,

Thx for your comment:)

LeaN said...

Great work man.
Easy and effective.

bonny said...

how can i call the
"handler.removeCallbacks(timedTask)" function from within the private method of the runnable?

SiouxGeonz said...

Thanks for a simple example that helps me understand the parts of the program! Now to go see if I can use it in my program :) ...