Android的消息机制
2017-09-20 本文已影响0人
wangdy12
-
MessageQueue
,消息队列,存放应该被处理的任务 -
Handler
,将任务加入到消息队列,执行其中取出的任务 -
Looper
,保证线程存活,循环MessageQueue
,取出其中的任务送到对应的Handler
-
Thread
,在调用了Looper的quit
方法以后才会终止,一个线程中只能有一个Looper
(内部包含一个MessageQueue
),可以有对应多个Handler
,创建Handler
时要求当前线程要有Looper
创建Looper和MessageQueue
在线程中调用Looper.prepare()
,创建当前线程对应的Looper
和MessageQueue
,存储在ThreadLocal
类中
然后通过Looper.loop()
开启消息循环(loop方法内部有一个死循环)
通过显示调用Looper.quit()
或者Looper.quitSafely()
退出
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
// this will run in non-ui/background thread
}
};
Looper.loop();
}
}
创建Handler
Handler
和实例化它的线程通过Looper
隐含关联
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// process incoming messages here
// this will run in the thread, which instantiates it
}
};
有两种方式将message发送到MessageQueue
中
-
Message
类,传递消息,有arg1,org2两个字段携带整形数据,obj字段携带任意Object对象,what用户自定义消息码
sendMessage(Message)
Message msg = new Message();
msg.obj = "Ali send message";
handler.sendMessage(msg);
产生一个Message对象,可以new Message(),也可以使用
Message.obtain()
方法;两者都可以,但是更建议使用obtain方法,因为Message内部维护了一个Message池用于Message的复用,避免使用new 重新分配内存
-
Runnable
,将Runable任务post到MessageQueue
post(Runnable),postDelayed(Runnable, long),内部实际上还是封装为Message
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// this will run in the main thread
}
});
HandlerThread
继承了Thread类,创建一个具有Looper的线程
方法一
依靠内部的同步机制,获取Handler
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
方法二
重载回调函数
@Override
protected void onLooperPrepared() {
handler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
// process incoming messages here
// this will run in non-ui/background thread
}
};