您的位置:首页 > 移动开发 > Android开发

android---HandlerThread源码分析

2016-04-14 10:48 429 查看
在上一篇我们分析了Handler的消息处理机制,我们也实现了在子线程中创建Handler对象,并且利用该Handler对象来处理了子线程自己发给自己的消息,但是要想让子线程中的Handler发挥作用,必须采用Looper.prepare( )来创建一个Looper对象,进而创建一个MessageQueue消息队列出来,随后调用Looper.loop( )方法来让消息队列运转起来;

我们来回顾下上一篇的实例:

public class MainActivity extends Activity {
public Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
System.out.println("message.what == 0");
break;
case 1:
System.out.println("message.what == 1");
break;
default:
break;
}
};
};
handler.sendEmptyMessage(0);
Looper.loop();
}
}).start();
}
}


输出结果:message.what == 0

但是你不觉得很麻烦么?我们每次都要添加Looper.prepare( )和Looper.loop( )方法,这一点android已经为我们考虑到啦,就是HandlerThread;

我们先来看看HandlerThread的一个实例:

public class MainActivity extends Activity {
public Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HandlerThread thread = new HandlerThread("huzhiwei");
thread.start();
Handler handler = new Handler(){

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
System.out.println("message.what == 0");
break;
case 1:
System.out.println("message.what == 1");
break;
default:
break;
}
}
};
handler.sendEmptyMessage(0);
}
}


输出结果:message.what == 0

解释:
(1)首先通过构造函数生成一个HandlerThread对象,参数是用于调试用的,具体没多大用途

(2)调用start方法开启线程

(3)生成一个Handler对象,并重写里面的handleMessage方法

这下子你可能就会疑问为什么HandlerThread里面没有执行Looper.prepare()和Looper.loop()方法就能进行接收和处理消息呢?别急,其实是HandlerThread帮你封装了而已的,看看HandlerThread的源码就知道啦

class HandlerThread extends Thread {
int mPriority;//线程优先级
int mTid = -1;//线程ID
Looper mLooper;//Looper对象

public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;//如果创建HandlerThread的时候没有线程优先级传入,则定义为默认优先级
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;//设置线程优先级
}
//这是监听方法,我们在创建HandlerThread的时候可以重写该方法,该方法会在run方法里面调用
protected void onLooperPrepared() {
}

@Override
public void run() {
mTid = Process.myTid();//获取线程ID
Looper.prepare();//生成Looper对象,同时创建MessageQueue消息队列,并且将Looper加入到ThreadLocal中
synchronized (this) {
mLooper = Looper.myLooper();//从ThreadLocal中获得Looper对象
notifyAll();
}
Process.setThreadPriority(mPriority);//设置线程的优先级
onLooperPrepared();//调用我们自己实现的回调方法
Looper.loop();//开始消息处理
mTid = -1;//将当前线程设置为invalid
}
public Looper getLooper() {
//如果当前线程不在ALIVE状态的话,直接返回null,说明我们没有执行start()方法
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();//一直等待,直到mLooper不为null
} catch (InterruptedException e) {
}
}
}
return mLooper;
}

public boolean quit() {
Looper looper = getLooper();//获得当前的Looper对象
if (looper != null) {
looper.quit();//退出
return true;
}
return false;
}
}
源码看注释就可以看懂了吧,这里有一个问题需要说明一下,在run方法里面有一个notifyAll()方法,getLooper方法里面有个wait()方法,这两个方法是相互匹配的,我们只有在run方法中创建了Looper对象才能在getLooper方法里面获取到该对象,如果run方法未创建的话,getLooper会执行wait方法一直等待,notifyAll会将原来在该对象上处于wait状态的线程全部结束其wait状态,因此wait和notifyAll是用来对生成Looper对象进行同步操作的;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: