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.
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>
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.
ReplyDeletehello unbrokenrabbit,
ReplyDeleteThx for your comment:)
Great work man.
ReplyDeleteEasy and effective.
how can i call the
ReplyDelete"handler.removeCallbacks(timedTask)" function from within the private method of the runnable?
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 :) ...
ReplyDelete