Handler作为Android的一个非常重要的异步消息机制。可以用以在不同的线程中传送和处理消息。
首先声明一个重点,在Android中要使Hanler对象工作,则首先需要Handler对象所出的线程中存在一个消息队列(MessageQueue),因此在创建Hander对象之前需要先创建一个Looper对象,有人也许会有疑问:Looper对象是干啥的呢?Looper从字面的意思看有点“循环器”的意思。它主要有两个重要的函数:Looper.prepare()和Looper.loop();Looper.prepare()用来创建一个消息队列,用来存放Message,loop()方法相当于循环从消息队列中取出Message并传给Handler的handlemessage()处理。
以下是一个简单的Handler Demo:
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button btn1 ;
private Handler myhandler; //若是把此行放到MyThread类中定义,则myhandler.sendEmptyMessage(123)会出错,因为外部类访问不了内部类变量。
class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare(); //要启动一个Handler需要线程中创立一个MessageQueue,所以先要创建一个Looper对象,
//再调用Looper.prepare()创建一个消息队列用来存放消息
myhandler = new Handler(){
@Override
public void handleMessage(Message msg){
if (msg.what == 123) {
Toast.makeText(MainActivity.this, "get msg :"+msg.toString(), Toast.LENGTH_SHORT).show();
};
}
};
Looper.loop(); //进入循环,从消息队列中取出消息给handler处理,若消息队列为空则循环暂停运行。
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.but1);
new MyThread().start();
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myhandler.sendEmptyMessage(123);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
因为是在新线程中创建Handler对象所以要先创建一个Looper对象用以创建一个MessageQueue。
而有的人会问为什么在主(UI)线程不用先创建一个Looper对象呢?
因为安卓程序在启动ActivityThread类中的主线程的时候会隐式的创建一个Looper对象并调用prepare方法创建一个MessageQueue。因此不需要再创建一个消息队列了,另外注意的是:一个Handler对象对应一个线程,而一个线程中只能有一个消息队列。