Handler Runnable Demo 学习_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Handler Runnable Demo 学习

Handler Runnable Demo 学习

 2011/11/2 8:10:33  Menuz  http://menuz.iteye.com  我要评论(0)
  • 摘要:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid
  • 标签:学习 Handler Runnable
<?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:layout_gravity="center"
		android:id="@+id/txt" />
	<Button android:id="@+id/btnStartTime" android:text="开始计时"
		android:layout_width="80dip" android:layout_height="wrap_content"></Button>
	<Button android:id="@+id/btnStopTime" android:text="停止计时"
		android:layout_width="80dip" android:layout_height="wrap_content" />
	<SeekBar android:layout_height="wrap_content"
		android:layout_width="fill_parent" android:id="@+id/SeekBar01"></SeekBar>
</LinearLayout>


例子通过Thread来模拟Handler的功能,利用Thread.sleep(1000)来
模拟1seconds,而每隔1s,Handler都会将当前剩余时间发到消息队列中,
Handler的构造函数之一Handler(Handler.CallBack),实现Handler.CallBack
中的handleMessage方法就能够获取Handler发出的消息。

HandlerExampleActivity01.java
package kping.example;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
public class HandlerExampleActivity01 extends Activity implements
        Handler.Callback, Button.OnClickListener {
    final static String TAG = "HandlerExampleActivity01";
    TextView txt;
    Button btnStart;
    Button btnStop;
    Handler myHandler;
    TimerThread timerThread;
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setupView();
    }
    public void setupView() {
        txt = (TextView) findViewById(R.id.txt);
        btnStart = (Button) findViewById(R.id.btnStartTime);
        btnStop = (Button) findViewById(R.id.btnStopTime);
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
        // Handler的构造函数之一Handler(Handler.Callback callback),所以HandlerExampleAcitivity01要实现
        //Handler.CallBack,从而实现handleMessage
        myHandler = new Handler(this);
        //打印主线程的id号
        Log.d(TAG, "ThreadId:" + String.valueOf(Thread.currentThread().getId()));
    }
 
    //     implements Handler.CallBack
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case 0:
            Bundle data = msg.getData();
            txt.setText(String.valueOf(data.getInt("time")));
 
            Log.d("ThreadId",
                "HandleMessage:"
                            + String.valueOf(Thread.currentThread().getId()));
            Log.d("ThreadId", "msgData:" + String.valueOf(data.getInt("time")));
            break;
        }
        return false;
    }
 
    //  implements Button.OnClickListener
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.btnStartTime:
            timerThread = new TimerThread(myHandler, 60);
            timerThread.start();
            break;
        case R.id.btnStopTime:
            timerThread.stop();
            break;
        }
    }
 
}


TimerThread.java
 
package kping.example;
 
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
 
public class TimerThread extends Thread {
    private final static String TAG = "TimerThread";
	private Handler handler;
	private int total;
 
	public TimerThread(Handler handler, int total) {
		this.handler = handler;
		this.total = total;
	}
 
	public void run() {
		while (true) {
			if(total < 0) 
				break;
			Message msg = new Message();
			Bundle data = new Bundle();
			data.putInt("time", total);
			msg.setData(data);
			msg.what = 0;
			Log.d(TAG, "ThreadId:" + String.valueOf(Thread.currentThread().getId()));
			handler.sendMessage(msg);
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			total--;
		}
	}
}



黄条是检测当前UI是否阻塞,后面有用到

ps:
这里stop按钮不起作用,可以给他设置个flag=false,需要添加一下逻辑,
另外start多按几下,logcat相应也会多出几个线程,程序要完善点,就对
timerThread添加些逻辑,若为null,才新建对象。不过这些不是重点,handler
大概意思传递到了就好

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).

上述字段摘自API中Handler的类说明
大致意思:可以有post(Runnable) sendMessage(Message)两种方法传递信息,其他都是在此基础上添加时间限制

下面再来一个例子,这里我们用内部类来实现Handler,所以不需要实现Handler.CallBack.当然post(Runnable)暗示主类要实现Runnable,与刚刚例子相比可以将TimerThread类撤掉,将记时功能也移至主类当中

HandlerExampleActivity02.java
package kping.example;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
public class HandlerExampleActivity02 extends Activity implements
        Button.OnClickListener{
    private final static String TAG = "HandlerExampleActivity02";
    private TextView txt;
    private Button btnStart;
    private Button btnStop;
    private int total = 8;
    private final Handler myHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 0:
                Bundle data = msg.getData();
                txt.setText(String.valueOf(data.getInt("time")));
                Log.d(TAG, data.getInt("time") + "");
                break;
            }
        }
    };
 
    private final Runnable runnable = new Runnable() {
 
        @Override
        public void run() {
            while (true) {
                if (total < 0)
                    break;
                Message msg = new Message();
                Bundle data = new Bundle();
                data.putInt("time", total);
                msg.setData(data);
                msg.what = 0;
                myHandler.sendMessage(msg);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                total--;
            }
        }
    };
 
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setupView();
    }
 
    public void setupView() {
        txt = (TextView) findViewById(R.id.txt);
        btnStart = (Button) findViewById(R.id.btnStartTime);
        btnStop = (Button) findViewById(R.id.btnStopTime);
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);
    }
 
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.btnStartTime:
            myHandler.post(runnable);   //触发run()
            break;
        case R.id.btnStopTime:
            myHandler.removeCallbacks(runnable);
            break;
        }
    }
}


之前我运行这个例子的时候一度以为出问题了,其实Thread.sleep()把主线程给睡了,把total设为60直接force close,令total=10还行,不过textView不会显示10,9,8.....而是10秒后直接显示0;logcat也是在10s后将10,9....0打印出来。这个例子其实可以优化,下面是我网上看到的一个例子。

HandlerExampleActivity03.java
package kping.example;
 
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 HandlerExampleActivity03 extends Activity {
    /** Called when the activity is first created. */
    private Button butStart;
    private Button butStop;
    TextView tv;
    int i = 0;
    Handler handler = new Handler();
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // Handler在那个Activity中new的就且仅属于那个Activity的
        butStart = (Button) findViewById(R.id.btnStartTime);
        butStop = (Button) findViewById(R.id.btnStopTime);
        tv = (TextView) findViewById(R.id.txt);
        butStart.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                handler.post(runnable);
            }
        });
        butStop.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                handler.removeCallbacks(runnable);
            }
        });
    }
 
    Runnable runnable = new Runnable() {
        public void run() {
            tv.setText(String.valueOf(i++));
            handler.postDelayed(runnable, 1000);
        }
    };
}


这个例子很清爽,之前用计数器弱爆了..
发表评论
用户名: 匿名