目录
具体使用:
简单介绍:
HandlerThread 他呢,继承了Thread,是一种可以使用Handler的Thread.那具体是怎么实现的呢?是因为他有Lopper,我们知道在子线程当中是不可以加载MessageQueen的,只有主线程才可以。所以Google封装了HandlerThread这样的框架,方面的供我们来使用!
HandlerThread在一个run方法中,我们通过Lopper.prepare()创建了消息队列,再通过Lopper.loop()就可以让消息循环了,那么接下类就可以在我们的线程中使用Handler.
同时注意在HandlerThread中同时只能处理一个事件,因为它添加了同步锁。
接下来我们可以看看源码更好的把知识点联系起来:
源码:
我们可以看到,继承了Thread,并且持有looper,然后传入了两个参数,一个是线程的名称,一个是优先级。
/**
* Handy class for starting a new thread that has a looper. The looper can then be
* used to create handler classes. Note that start() must still be called.
*/
public class HandlerThread extends Thread {
int mPriority;//线程优先级
int mTid = -1;
Looper mLooper;//当前线程持有的Looper对象
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
/**
* Constructs a HandlerThread.
* @param name
* @param priority The priority to run the thread at. The value supplied must be from
* {@link android.os.Process} and not from java.lang.Thread.
*/
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
/**
* Call back method that can be explicitly overridden if needed to execute some
* setup before Looper loops.
*/
protected void onLooperPrepared() {
}
接下来看我们的run方法,当HandlerThread启动以后,执行run方法,初始化并启动Lopper,把lopper对象传给hanlderMessage,执行异步操作。这里我们可以看到他通过看同步锁来限制了任务,通过判断当前任务是否执行,如果启动了,就会判断Lopper是否为空,如果为null,也就是说对象还没有被创建,就会等待。反之若有值,则唤醒线程!
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll(); //唤醒等待线程
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
这里我们需要一个等待机制解决同步问题:通过了判断是否创建Lopper对象,保证了调用getLopper()方法时已经创建了Lopper对象。
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;
}
具体使用:
1.启动HandlerThread
//创建异步HandlerThread
HandlerThread handlerThread = new HandlerThread("downloadImage");
//必须先开启线程
handlerThread.start();
//子线程Handler
Handler childHandler = new Handler(handlerThread.getLooper(),new ChildCallback());
2.构建消息处理机制:
/**
* 该callback运行于子线程
*/
class ChildCallback implements Handler.Callback {
@Override
public boolean handleMessage(Message msg) {
//在子线程中进行相应的网络请求
//通知主线程去更新UI
mUIHandler.sendMessage(msg1);
return false;
}
}