Android消息处理系统
1.Handler
handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
它有两个作用: (1): 安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行
mLooper---------Looper.myLooper()
mQueue----------mLooper.mQueue--------Looper::mQueue
//发送一个消息
sendMessage(Message msg){
msg.target = Handler.this;
mQueue.enqueueMessage(msg);
}
//接受一个消息进行处理
dispatchMessage(Message msg){
Handler.this.handleMessage(msg);
}
2.Looper
(1) Looper类别用来为一个线程开启一个消息循环。默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环)
Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。
(2) 通常是通过Handler对象来与Looper交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。
开启消息循环调用如下
{
Looper.prepare() ; // or Looper.prepareMainLooper();
...
Looper.loop();
}
重要成员变量及函数:
ThreadLocal<Looper> sThreadLocal;
MessageQueue mQueue;
prepare(){
sThreadLocal.set(new Looper());
}
loop(){
Looper me = sThreadLocal.get();
while(1){
Message msg = mQueue.next();
msg.target.dispatchMessage(msg);
}
}
myLooper(){
return sThreadLocal.get();
}
3.Message
重要成员变量及函数
int what
int arg1;
int arg2;
Handler target;
Message next;
Object obj;
Message obtain(){
return new Message();
}
recycle(){...}
4.消息队列MessageQueue
重要成员变量及函数
Message mMessages;
ArrayList<IdleHandler> mIdleHandlers;
IdleHandler[] mPendingIdleHandlers;
Message next(){
//操纵mMessages;
}
enqueueMessage(Message msg){
//加入mMessage的头部或尾部
}
removeMessage(Message msg){...}
消息处理流程
1.Activity在启动时会通过ActivityThread调用Looper.prepareMainLooper()和Looper.loop()开启消息循环
发送一个消息
2.Handler.sendMessage(msg);
3.Handler::mQueue::enqueueMessage(msg);
即Looper::mQueue(msg);
消息被压入消息队列
4.在Looper::loop()中处理消息;
5.msg.dipatchMessage(msg);
5.Handler::handleMessage(msg);
eg:
xxxActivity extends Activity{
public static final int MSG_TEST = 101;
...
Handler mHandler = new Handelr(){
public void handleMessage(Message msg){
if(msg.what==MSG_TEST){
Log.v("xxxActivity", "get message MSG_TEST");
}
}
};
...
new Thread(){
public void run(){
Message msg = new Message();
msg.what = MSG_TEST;
Log.v("xxxActivity", "send message MSG_TEST in new thread");
mHandler.sendEmptyMessage(msg);
}
}.start();
}