Handler & Message
Handler和Message是Android系统提供的一套异步消息处理机制。为了易于理解,我们可以把Handler形象得看成是邮局,而Massage则可以看成是信件,寄信人把信件(Message)拿到邮局(Handler),邮局把信件送到收信人手里。除此之外,Handler还可以把一个线程压入UI的线程队列中。
一、Hanler提供以下方法(只例举了部分),用于将一个线程压入UI的线程队列中:
1.post(Runnable r)
2.postAtFrontOfQueue(Runnable r)
3.postAtTime(Runnable r, Object token, long uptimeMillis)
4.postAtTime(Runnable r, long uptimeMillis)
5.postDelayed(Runnable r, long delayMillis)
二、Hanler提供以下方法(只例举了部分),用于将一个线程从UI的线程队列中删除:
1.removeCallbacks(Runnable r)
2.removeCallbacks(Runnable r, Object token)
三、Hanler提供以下方法(只例举了部分),用于获得一个消息对象:
1.obtainMessage()
2.obtainMessage(int what)
3.obtainMessage(int what, int arg1, int arg2)
4.obtainMessage(int what, int arg1, int arg2, Object obj)
四、Hanler提供以下方法(只例举了部分),用于将一个消息压入UI的消息队列:
1.sendMessage(Message msg)
2.sendMessageAtFrontOfQueue(Message msg)
3.sendMessageAtTime(Message msg, long uptimeMillis)
4.sendMessageDelayed(Message msg, long delayMillis)
五、提供以下方法,用于从UI的消息队列中读取一个消息:
1.handleMessage(Message msg)
说明:这里有一点是必须要引起我们注意的,使用Handler的post()系列方法将一个线程压入UI的线程队列中,相当于直接运行Runnble的run()方法,系统不会从新开启一个新的线程,如果压入UI线程队列中的线程耗时较长,则会阻塞UI线程;要想系统重新开辟一个新线程,即使该子线程耗时较长也不会引起UI线程阻塞,可以使用Thread的start()方法启动该线程,如下所示:
Thread mThread = new Thread(mRunnable);
mThread.start();
Java源代码:
package com.zhou.handlermessagedemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private final String tag = new String("Zhou");
private Button startButton = null;
private Button mButton = null;
private TextView textView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textview);
startButton = (Button)findViewById(R.id.button_start);
startButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
/*
* 采用post()方法将线程压入UI线程的线程队列中(没有新开辟线程),
* 如直接调用Runnble类中的run()方法,UI线程还是会被阻塞。
*/
// mHandler.post(mRunnable);
/*
* 采用线程的start()方法启动线程,此时是新开辟了一个线程,
* 使用这样的方法启动新线程,UI线程不会被阻塞。
*/
Thread mThread = new Thread(mRunnable);
mThread.start();
}
});
mButton = (Button)findViewById(R.id.button);
mButton.setOnClickListener(new OnClickListener() {
int i = 0;
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
textView.setText(i++ + "");
}
});
Log.d(tag, "MainThreadName:" + Thread.currentThread().getName());
Log.d(tag, "MainThreadId:" + Integer.toString((int)Thread.currentThread().getId()));
}
private static Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Log.d("Zhou", msg.what + "");
}
};
private Runnable mRunnable = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.d(tag, "SubThreadName:" + Thread.currentThread().getName());
Log.d(tag, "SubThreadId:" + Integer.toString((int)Thread.currentThread().getId()));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = mHandler.obtainMessage(123);
mHandler.sendMessage(msg);
}
};
}