android的消息处理机制有三个核心的类:Looper,Handler,Message
Looper
一个线程产生一个looper实例,负责创建一个MessageQueue,然后无限循环的在消息队列里读取信息(管理线程里的消息队列)。
主要使用两个方法:prepare()和loop()
每个线程都可以有自己的消息队列和消息循环,可以通过继承Thread来创建一个Looper线程:
<pre name="code" class="java">public class LooperThread extends Thread {
@Override
public void run() {
// 将当前线程初始化为Looper线程
Looper.prepare();
// ...其他处理,如实例化handler
//mHandler = new Handler() {
// public void handleMessage(Message msg) {
// process incoming messages here
}
};
// 开始循环处理消息队列
Looper.loop();
}
}
当
调用loop()方法后,Looper线程就开始真正工作了,它不断从自己的MQ中取出队头的消息(也叫任务)执行。
android中是使用Looper机制来完成消息循环的,但每次创建线程时都先初始化Looper比较麻烦,因此Android为我们提供了一个HandlerThread类,他封装了Looper对象,是我们不用关心Looper的开启和释放问题。
不管是主线程还是其他线程只要有Looper的线程,别的线程就可以向这个线程的消息队列中发送消息和任务。
有了消息队列,就可以放入消息了。下面看Handler。
Handler
负责往MQ添加消息和处理消息(只处理自己添加的消息)。
Handler发送消息
handler的API提供了几种发送消息的方法
<pre name="code" class="java">/**
* 它安排消息,用以下方法
* post(Runnable r);
* postAtTime(Runnable r, long uptimeMillis);
* postDelayed(Runnable r, long delayMillis);
* sendEmptyMessage(int what);
* sendMessage(Message msg);
* sendEmptyMessageAtTime(int what, long uptimeMillis);
* sendEmptyMessageDelayed(int what, long delayMillis);
* 以上方法以 post开头的可以处理Runnable对象
* sendMessage()可以处理Message对象(Message里可以包含数据,)
*/
从API中可以看出handler能发两种消息,一种是Runnable对象,一种是message对象。这里不详解
Handler消息处理
handler对消息的处理是通过核心方法dispatchMessage(Message msg)与钩子方法handleMessage(Message msg)完成的
dispatchMessage(Message msg)由looper调用,在我们自己写的代码中经常使用的是handleMessage(Message msg)来处理消息
下面的方法是官方提供的API中的方法,是一个空方法,就可以知道这个方法由我们自己写。
public void handleMessage(Message msg) {
}
Handler不仅可以更新UI,还可以在一个子线程中去创建一个Handler,然后使用这个handler实例在任何其他线程中发送消息,最终处理消息的代码都会在你创建Handler实例的线程中运行,大致方法和创建looper线程相同。下面是一个实例:
<pre name="code" class="java">new Thread()
{
private Handler handler;
public void run()
{
Looper.prepare();
handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
Log.e("TAG",Thread.currentThread().getName());
};
};
Looper.loop();
}
下面我们说一下Message
Message
在整个消息处理机制中,message又叫task,封装了任务携带的信息和处理该任务的handler。message的用法比较简单,这里不做总结了。但是有这么几点需要注意(待补充):
1.尽管Message有public的默认构造方法,但是你应该通过Message.obtain()来从消息池中获得空消息对象,以节省资源。可以通过removeMessages()从消息队列里删除消息。
2.如果你的message只需要携带简单的int信息,请优先使用Message.arg1和Message.arg2来传递信息,这比用Bundle更省内存
3.擅用message.what来标识信息,以便用不同方式处理message。
4.还可以使用Handler对象的obtainMessage()方法从消息池里取出消息
Message 可以传递的参数有:
1. arg1 arg2 整数类型,是setData的低成本替代品。传递简单类型
2. Object 类型 obj
3. what 用户自定义的消息代码,这样接受者可以了解这个消息的信息。每个handler各自包含自己的消息代码,所以不用担心自定义的消息跟其他handlers有冲突。
4.其他的可以通过Bundle进行传递
Message可以通过new Message构造来创建一个新的Message,但是这种方式很不好,不建议使用。最好使用Message.obtain()来获取Message实例,它创建了消息池来处理的。
下面以用一张图总结android的消息处理机制
以上是我的一些简单理解,想要更加深入理解可以点击下面的网址
http://www.cnblogs.com/codingmyworld/archive/2011/09/14/2174255.html
http://www.cnblogs.com/codingmyworld/archive/2011/09/14/2174255.html