一、概述
HandlerThread 看名字,应该包含Handler和Thread,然而,你以为你以为的就是你以为的?哈哈。 开个玩笑,言归正传。 HandlerThread 继承自Thread,自身包含一个Looper。或许你该问,既然没有Handler相关的东西,为什么交HandlerThread。其实这个跟Android的Handler工作机制相关,Handler对象的生成是需要在有Looper的线程中,如果在没有Looper的线程中生成Handler对象,将会爆出异常。
IntentService 是一个继承自Service的类,他内部实现原理是依赖HandlerThread来实现的,IntentService启动了一个后台服务,在该后台服务中启动一个线程来工作,当线程工作完后,自动的安全关闭该服务,避免耗费资源。
二、源码分析
还是结合源码来分析这两个类的工作原理,首先看下HandlerThread的源码实现,源码不是很多,我就全部放进来了:
public class HandlerThread extends Thread {//继承自Thread类
int mPriority;
int mTid = -1;
Looper mLooper;//内部维护一个Looper
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;//线程优先级用的默认优先级
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() { //用户可以重写该方法,在Looper.loop()之前做一些准备工作
}
@Override
public void run() {//线程体执行的内容
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();//获得一个Looper
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();//hook onLooperPrepared
Looper.loop();//启动消息循环
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
从上述代码中可以看出:
1.HandlerThread确实是一个线程;
2.HandlerThread中维护了一个Looper对象,在线程执行体内启动了Looper.loop()。
下面看下IntentService的源码,代码量也不是很多:
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;//内部使用了一个Handler
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);//收到消息后,回调onHandleIntent()方法 注意该方法的调用是在非主线程中调用的
stopSelf(msg.arg1);//待线程体执行结束后,结束该服务
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");//在Service
OnCreate中,使用HandlerThread 启动一个带Looper的线程
thread.start();
mServiceLooper = thread.getLooper();//获取到Looper
mServiceHandler = new ServiceHandler(mServiceLooper);//生成一个Handler ,前边讲过,Handler的生成需要Looper。
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);//在onStart()方法中发送一个消息
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);//重写方法 讲耗时的内容在该方法体实现
}
三、总结
通过上边两个类的源码分析,我们可以总结出:
1.HandlerThread是一个线程,在线程启动的时候启动消息队列;
2.IntentService 是一个继承自Service的类,他通过在Service服务中开启HandlerThread的消息队列;
3.使用HandlerThread的Looper来生成一个Handler对象,在onStart()方法中发送消息,然后执行onHandleIntent()方法;
4.onHandleIntent在子线程中执行,我们可以将耗时任务放在这个方法中实现。
至于Handler机制不在本文讨论,但本文的理解需要基于Handler工作机制。有机会再给大家分析Handler的工作机制。
感谢你的耐心阅读,如有错误,欢迎指正。如果本文对你有帮助,记得点赞.