1、Looper
Looper用于封装了android线程中的消息循环,并且拥有一个消息队列。
(1)、Looper.prepare()来给线程创建一个消息循环
(2)、Looper.loop()来使消息循环起作用,从消息队列里取消息,处理消息。注意:消息循环完毕后,Looper.loop()内部会结束整个子线程的执行, 所以Looper.loop()之后的语句是不会运行的。
注:写在Looper.loop()之后的代码不会被立即执行,当调用后mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。
一个典型的Looper thread实现:
class LooperThread extends Thread
{
public Handler mHandler;
public void run()
{
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
// process incoming messages here
}
};
Looper.loop();
}
2、handler
handler类,有点像辅助类,封装了消息投递和处理等API。
handler的消息处理:
Looper获取消息后会调用target的dispatchMessage函数来处理,我们可以看下handler的dispatchMessage实现,看看handler是怎么处理消息的。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
可以看到:
(1)如果message有自己的callback,那先调用该callback来处理
(2)其次如果handler设置了mCallback,调用mCallback的handleMessage处理
(3)最后才是调用handler子类的handleMessage来处理
一般来说,handler的使用,最经常的就是两种:
一种是handler.sendMessage。发一个消息,再根据消息,执行相关任务代码,也就是上面说的dispatchMessage调用的方式。
另一种是调用handler的post方法。这种一开始看有点不知道什么意思意思,post方法的参数是Runnable对象,如下:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
其实就是将Runnable对象添加到消息队列中去,然后Runnable对象会运行在Handler依附的线程里。
3、HandlerThread
使用handler和looper的时候,经常会遇到的问题是同步不好造成一些bug。
使用HandlerThread可以解决这个问题,它使用了wait和notify来做了同步操作,这样在looper已经创建出来后,我们才能拿到。
我们可以看下android的实现:
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
使用方法:
(1)创建一个HandlerThread,即创建了一个包含Looper的线程。
HandlerThread handlerThread = new HandlerThread(“xxx”);
(2)handlerThread.start(); //创建HandlerThread后一定要记得start()
(3)获取HandlerThread的Looper
Looper looper = handlerThread.getLooper();
(4)创建Handler,通过Looper初始化
Handler handler = new Handler(looper);
我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。
如果想让HandlerThread退出,则需要调用handlerThread.quit();。