轻松的,随心所欲的解释,才会让代码变得更简单!
1、what is this ?
顾名思义:Handler+Thread实现的一个类,轻量级异步通信,通过Handler实现子线程与主线程的通信
2、How to use ?
Let me show you something ,so easy!
咋们先从开始使用再到源码剖析,准备上车!
五步走战略策略 :
//step 1:创建HandlerThread对象,参数说明:线程名称 or 线程名称+线程优先级
HandlerThread mHandlerThread = new HandlerThread("yourname");
//step 2:启动线程,创建Looper对象,MessageQuene,开启消息循环
mHandlerThread.start();
//step 3:通过HandlerThread的Looper对象创建搬砖线程,复写handleMessage()方法,实现子线程
与主线程的通信,handleMessage()方法其实是执行在HandlerThread 创建的子线程内
static Handler moveBrickHandler = new Handler( mHandlerThread.getLooper() ) {
@Override
public boolean handleMessage(Message msg) {
//消息处理
return true;
}
});
//step 4:通过sendMessage()向搬砖线程发送消息,进行消息传递
Message message = Message.obtain();
//消息标识
message .what = FLAG
//消息体
message.obj = OBJECT
//通过搬砖Handler发送消息
moveBrickHandler.sendMessage(message);
//step 5:停止消息,分为两种,后面将会一一解释
mHandlerThread.quit();
//安全退出
mHandlerThread.quitSafely();
这里就不上案例了,很简单,按照上面使用即可!
OK,congratulation! 你已经熟练掌握其使用方法了------ nice, 就这!
3、源码套餐解析一波,请收下它
我们将会根据上面的使用不步骤来一步步讲解源码,建议先了解Handler的使用及原理,才有利于消化哟,Let’s begin !!
step 1:创建HandlerThread对象,参数说明:线程名称 or 线程名称+线程优先级
//继承自Thread类,是一个线程Thread类
public class HandlerThread extends Thread {
//线程优先级
int mPriority;
//当前线程id
int mTid = -1;
//当前线程持有的Looper对象
Looper mLooper;
//默认优先级
public HandlerThread(String name) {
//通过调用父类默认的方法创建线程
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
//自定义设置优先级
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
//-------------------------//
}
step 2:启动线程,创建Looper对象,MessageQuene,开启消息循环
/**
* 源码分析:通过调用start()方法,从而调用到run()方法
*/
@Override
public void run() {
//setup 1. 获得当前线程的id
mTid = Process.myTid();
//setup 2. 创建Looper对象以及MessageQueue对象,不清楚的建议先阅读Handler源码
Looper.prepare();
//setup 3. 通过持有锁机制来获得当前线程的Looper对象
synchronized (this) {
mLooper = Looper.myLooper();
//发出通知:当前线程已经成功创建mLooper对象,通知getLooper()方法中的wait()
notifyAll();
}
//setup 4. 设置当前线程的优先级
Process.setThreadPriority(mPriority);
//setup 5. 在线程循环前做一些准备工作,该方法实现体是空的,子类可实现 or 不实现该方法
onLooperPrepared();
//setup 6. 进行消息循环,不断从MessageQueue中取消息 and 派发消息
Looper.loop();
//setup 7. 重置线程id
mTid = -1;
}
//子类选择性实现,主要作为初始化工作
protected void onLooperPrepared() {
}
step 3:通过HandlerThread的Looper对象创建搬砖线程,复写handleMessage()方法,实现子线程与主线程的通信,handleMessage()方法其实是执行在HandlerThread 创建的子线程内,这里主要介绍HandlerThread的getLooper()方法,关于创建Handler可以去了解Handler的创建过程
/**
*getLooper()返回mLooper对象最终是在run()方法中返回,Looper.myLooper()
*/
public Looper getLooper() {
//判断线程是否存活
if (!isAlive()) {
return null;
}
//通过锁机制来实现wait(),notifyAll()
synchronized (this) {
//循环判断线程是否存活,以及mLooper对象是否为null
while (isAlive() && mLooper == null) {
try {
//调用wait()方法等待
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
step 4:通过sendMessage()向搬砖线程发送消息,进行消息传递,此处为Handler相关,暂不作具体分析
Message message = Message.obtain();
//消息标识
message .what = FLAG
//消息体
message.obj = OBJECT
//通过搬砖Handler发送消息
moveBrickHandler.sendMessage(message);
step 5:停止消息,分为安全的停止消息和不安全的停止消息,无论是那种方式,最终都会调用MessageQueue的quit(boolean safe)方法
/**
*MessageQueue.quit(boolean safe)
*/
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}
synchronized (this) {
//是否已经退出,是的话直接返回
if (mQuitting) {
return;
}
mQuitting = true;
//是否选择安全退出
if (safe) {
//安全退出,首先会判断是否有消息正在处理
removeAllFutureMessagesLocked();
} else {
//不安全的退出,直接遍历列表,移除消息
removeAllMessagesLocked();
}
nativeWake(mPtr);
}
}
/**
*遍历Message链表、移除所有消息的回调,重置message为null
*/
private void removeAllMessagesLocked() {
Message p = mMessages;
//遍历Message链表、移除所有消息的回调
while (p != null) {
Message n = p.next;
p.recycleUnchecked();
p = n;
}
mMessages = null;
}
/**
*判断当前消息队列是否正在处理消息
*若不是,则调用removeAllMessagesLocked()移除消息
*若是,则等待该消息处理处理完毕再调用removeAllMessagesLocked()移除消息
*/
private void removeAllFutureMessagesLocked() {
final long now = SystemClock.uptimeMillis();
Message p = mMessages;
if (p != null) {
// 判断当前消息队列是否正在处理消息
if (p.when > now) {
//没有,直接移除所有消息
removeAllMessagesLocked();
} else {
//若是正在处理,则等待该消息处理处理完毕再退出该循环
Message n;
//循环获取消息
for (;;) {
n = p.next;
if (n == null) {
return;
}
if (n.when > now) {
break;
}
p = n;
}
p.next = null;
do {
p = n;
n = p.next;
p.recycleUnchecked();
} while (n != null);
}
}
}
以上就是大致情况,建议先了解Handler以及Thread,你会更好的理解HandlerThread 哟
最后一步,小结一哈!
- 创建HandlerThread 的过程,其实就是创建Thread的过程,通过传入参数线程名称 and
线程名称和优先级,来创建HandlerThread ,这里的优先级为Android里面的优先
Process.THREAD_PRIORITY_DEFAULT - 调用HanderThread的start()方法来启动线程,其实是调用Thread的start(),就会回调run()方法,首先是创建MessageQueue以及Looper对象,通过锁机制 wait()与notifyAll()来获取当前线程的mLooper对象,当mLooper对象为空时,getLooper()通过wait()会阻塞,只有当mLooper对象被成功初始化时,通过notifyAll()唤醒,然后通过Looper.loop() 开启循环,不断从messageQueue中取出消息
- 通过HandlerThread的getLooper()获取mLooper对象,通过该looper对象创建Handler,实现与HandlerThread创建的线程进行绑定
- 消息的停止,分为安全停止与不安全的停止方式,主要区别在于停止消息时,对是否有消息正在进行处理作出不同反应,安全方式需要等待消息执行完之后才会停止,不安全则是直接遍历消息列表,移除消息,重置message