今天看到Handler消息处理机制,实现一个Handler+Thread.sleep的简单计时器
Handler
我的理解:
因为子线程不允许更新UI,那就利用Handler对象的sendMessage(Message msg)方法把更新消息传递
给UI线程对UI进行更新
官方文档:
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, Object, 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.
Google在线翻译:
Handler允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。 每个Handler实例都与一个线程和该线程的消息队列相关联。 当您创建一个新的Handler时,它被绑定到正在创建它的线程的线程/消息队列 - 从那时起,它将消息和runnables传递给该消息队列并在消息出来时执行它们 队列。
Handler有两个主要用途:(1)安排消息和runnables作为未来某些点执行; (2)将要在不同于自己的线程上执行的动作排入队列。
调度消息是通过post(Runnable),postAtTime(Runnable,long),postDelayed(Runnable,Object,long),sendEmptyMessage(int),sendMessage(Message),sendMessageAtTime(Message,long)和sendMessageDelayed(Message,long)方法来完成的。 post版本允许您将Runnable对象排入队列,以便在收到它们时由消息队列调用; sendMessage版本允许您将包含将由Handler的handleMessage(Message)方法处理的数据包的Message对象排入队列(要求您实现Handler的子类)。
发布或发送到处理程序时,您可以在消息队列准备好后立即允许处理该项目,或者在处理之前指定延迟或处理它的绝对时间。后两者允许您实现超时,滴答和其他基于时间的行为。
为应用程序创建进程时,其主线程专用于运行消息队列,该队列负责管理顶级应用程序对象(活动,广播接收器等)以及它们创建的任何窗口。您可以创建自己的线程,并通过Handler与主应用程序线程进行通信。这是通过调用与以前相同的post或sendMessage方法完成的,但是来自新的线程。然后,将在Handler的消息队列中调度给定的Runnable或Message,并在适当时进行处理。
Public methods | |
---|---|
static Handler | createAsync(Looper looper, Handler.Callback callback) Create a new Handler whose posted messages and runnables are not subject to synchronization barriers such as display vsync. |
static Handler | createAsync(Looper looper) Create a new Handler whose posted messages and runnables are not subject to synchronization barriers such as display vsync. |
final Looper | getLooper() |
String | getMessageName(Message message) Returns a string representing the name of the specified message. |
void | handleMessage(Message msg) Subclasses must implement this to receive messages. |
…… | …… |
final boolean | post(Runnable r) Causes the Runnable r to be added to the message queue. |
……… | |
final boolean | sendMessage(Message msg) Pushes a message onto the end of the message queue after all pending messages before the current time. |
代码:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TimerActivity extends Activity {
private TextView timeHourText,timeMinText,timeSecText;
private Button startBtn;
private Handler handler=new Handler() {
public void handleMessage(android.os.Message message){
//运行在主线程
switch (message.what){
case 0x001:
timeHourText.setText(message.arg1/3600+" ");
timeMinText.setText(message.arg1/60+" ");
timeSecText.setText(message.arg1%60+" ");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
timeHourText=(TextView)findViewById(R.id.tvHour);
timeMinText=(TextView)findViewById(R.id.tvMin);
timeSecText=(TextView)findViewById(R.id.tvSec);
startBtn=(Button)findViewById(R.id.btnStart);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Thread的匿名类
new Thread(){
public void run(){
int i=0;
while (true){
Message message=new Message();
message.what=0x001;//消息的标识,必须有
message.arg1=i;
handler.sendMessage(message);
try {
Thread.sleep(1000);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
});
}
}