Android Handler定时更新UI

openkk 9年前

     Handler在android里负责发送和处理消息。它的主要用途有:
        1)按计划发送消息或执行某个Runnanble(使用POST方法);
        2)从其他线程中发送来的消息放入消息队列中,避免线程冲突(常见于更新UI线程)
         默认情况下,Handler接受的是当前线程下的消息循环实例(使用Handler(Looper looper)、Handler(Looper looper, Handler.Callback callback) 可以指定线程),同时一个消息队列可以被当前线程中的多个对象进行分发、处理(在UI线程中,系统已经有一个Activity来处理了,你可以再起若干个 Handler来处理)。在实例化Handler的时候,Looper可以是任意线程的,只要有Handler的指针,任何线程也都可以 sendMessage。Handler对于Message的处理不是并发的。一个Looper 只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的(handleMessage()方法里不应该有耗时操作,可以将耗时操作放在 其他线程执行,操作完后发送Message(通过sendMessges方法),然后由handleMessage()更新UI)。
参考 android.os.Handler 的文档 
引用

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. 


</div>
下面是个计数器演示代码
Android Handler定时更新UI Android Handler定时更新UI

Java 代码
package artray.cjp.counterdemo;

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


public class CounterDemoActivity extends Activity {

    private Button btnStart;  
    private Button btnStop;  
    private Button btnReset;  
    private TextView tvCounter;  
    private long count = 0;  
    private boolean run = false;  
  
    private Handler handler = new Handler();  
  
    private Runnable task = new Runnable() {  
  
        public void run() {  
            // TODO Auto-generated method stub  
            if (run) {  
                handler.postDelayed(this, 1000);  
                count++;  
            }  
            tvCounter.setText("Count: " + count);  
        }  
    };  
  
    /** Called when the activity is first created. */  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
  
        btnStart = (Button) findViewById(R.id.Button01);  
        btnStop = (Button) findViewById(R.id.Button02);  
        btnReset = (Button) findViewById(R.id.Button03);  
        tvCounter = (TextView) findViewById(R.id.counter);  
  
        btnStart.setOnClickListener(new OnClickListener() {  
  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                run = true;  
                updateButton();  
                handler.postDelayed(task, 1000);  
            }  
        });  
  
        btnStop.setOnClickListener(new OnClickListener() {  
  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                run = false;  
                updateButton();  
                handler.post(task);  
            }  
        });  
  
        btnReset.setOnClickListener(new OnClickListener() {  
  
            public void onClick(View v) {  
                // TODO Auto-generated method stub  
                count = 0;  
                run = false;  
                updateButton();  
                handler.post(task);  
            }  
        });  
    }  
  
    private void updateButton() {  
        btnStart.setEnabled(!run);  
        btnStop.setEnabled(run);  
    }  
}
</span>