一. Handler,Looper,MessageQueen间的关系
Looper:每个线程只有一个Looper,它负责管理MessageQueen,会不断的从MessageQueen中取出消息,并将消息分给对应的Handler处理。
MessageQueen:由Looper负责管理,它采用先进先出的方式管理Message
Handler:它把消息发送给由Looper管理的MessageQueen,并负责处理Looper给它的消息
二. Handler用法
1. 调用obtainMessage方法获取Message对象就能避免创建对象,从而减少内存的开销
2. Handler中obtainMessage与new Message的区别:
obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间。
new Message()需要重新申请,效率低,obtianmessage()可以循环利用;
第一种写法是message 从handler 类获取,从而可以直接向该handler对象发送消息,第二种写法是直接调用 handler 的发送消息方法发送消息。
3. post(Runnable r)和sendMessage(Message msg)区别:
1). 一个Handler只有一个队列;
2). 在调用Handler.post(Runnable runnable)方法时,会将runnable封装成一个Message;
3). 在队列执行时,会判断当前的Message里是否封装了Runnable,如果封闭了,就直接执行Runnable,如果没有,将当前的Message传递给handleMessage(Message msg)处理;
源代码如下:
public final boolean sendMessage(Messagemsg){
return sendMessageDelayed(msg, 0);
}
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
private final Message getPostMessage(Runnable r) {
Message m =Message.obtain();
m.callback = r;
return m;
}
区别是:在调用Handler.post(Runnable runnable)方法时,会将runnable封装成一个Message;
4. Handler在实例化的时候可以设置一个callback<Handler.Callback>,callback也有一个handleMessage(Messagemsg)方法,测试结果如下:
class MyCallback implementsandroid.os.Handler.Callback{
@Override
public boolean handleMessage(Messagemsg) {
Log.d("FF","MyCallback--->handleMessage");
return true;// return false;-----------------------------------------------------位置1
}
}
private Handler mCallbackHandler = new Handler(new MyCallback()){
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
Log.d("FF","mCallbackHandler--->handleMessage");-------------------位置2
}
};
private void buttonClick2(){
mCallbackHandler.sendEmptyMessage(0);
}。
测试结果:
位置1:callback的handleMessage(Message msg)
位置2:自身的handleMessage(Message msg)
若位置1是return false时,位置2会被调用
若位置1是return true时,位置2则不会被调用
三. HandlerThread用法
1. 继承于Thread,所以HandlerThread本质就是一个线程
2. HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息
3.
(1)为什么要使用HandlerThread?
在我们的应用程序当中为了实现同时完成多个任务,所以我们会在应用程序当中创建多个线程。为了让多个线程之间能够方便的通信,我们会使用Handler实现线程间的通信。
(2)如何在线程当中实例化Handler?
在线程中实例化Handler我们需要保证线程当中包含Looper(注意:UI-Thread默认包含Looper)。
为线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)
(3) HandlerThread就是实现Looper更加简单的方法。官网描述如下:
Handy class forstarting a new thread that has a looper. The looper can then be used to createhandler classes. Note that start() must still be called.
尽管HandlerThread的文档比较简单,但是它的使用并没有想象的那么easy。
1. 创建一个HandlerThread,即创建了一个包含Looper的线程。
HandlerThreadhandlerThread = new HandlerThread("leochin.com");
handlerThread.start();//创建HandlerThread后一定要记得start()
2. 获取HandlerThread的Looper
Looper looper =handlerThread.getLooper();
3. 创建Handler,通过Looper初始化
Handler handler =new Handler(looper);
通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。
如果想让HandlerThread退出,则需要调用handlerThread.quit()
HandlerThread源代码如下:
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
Process.setThreadPriority(mPriority);
notifyAll();
}
onLooperPrepared();
Looper.loop();
mTid = -1;
}