HandlerThread
HandlerThread是一个线程,内部并没有Handler,而是一个为子线程中可以使用Handler而创建了Looper并开启了Looper.loop()
循环的线程。也就是说HandlerThread绑定了Looper。
产生背景
子线程开启进行耗时操作实现方式很简单,但是为什么Android还会专门为此封装一个类来操作呢,直接写个线程也没多写多少代码,但是想想,线程的创建和销毁也是需要消耗系统资源的,一次的创建销毁不会有太大的问题,假如多次的数据操作时,多次的创建和销毁线程就会很耗系统资源了。
但是使用HandlerThread也有个缺点,消息队列处理消息是串行的,实际只是一个线程处理多个任务,效率偏低、
实现原理
HandlerThread的源码非常简短,只有短短的150行,创建逻辑也很清晰
和我们平时在子线程开启Looper,使用Handler的方式类似,HandlerThread在run()方法里绑定了Looper,方便了想使用异步消息机制的场景
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
并且提供了退出的方法,当我们不需要线程运行的时候,可以调用退出方法,退出。
如何使用
HandlerThread的提供了onLooperPrepared()
方法,表示Looper已经创建,此时可以在该方法里创建Handler来发送消息,此方法在HandlerThread的run()方法里调用的,当然HandlerThread还提供了获取Looper的方法,我们可以在创建Handler的时候,接收此Looper对象来绑定该线程的looper,效果是一样的
//IntentService内部Handler的使用体现
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
IntentService
Android中四大组件内都是不可以进行耗时的操作的,而因为Service的优先级比较高,并且往往用来进行一些优先级比较高的后台任务。所以Service + HandlerThread 是一个很好的组合,所有就有了IntentService。
- IntentService是继承Service的一个抽象类,使用他需要继承IntentService,当IntentService第一启动时,会走onCreate()
的生命周期,此时初始化了HandlerThread和Handler(ServiceHandler)将Handler和子线程的Looper绑定了,这样我们就可以在这个Service所提供的方法onHandleIntent()
里执行一个耗时等后台任务了。
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
我们在启动Service时使用Intent传递了数据,当startService()时,Intent携带数据,会走到 onStartCommand(Intent intent, int flags, int startId)
该方法最终经过IntentService内部的Handler(ServiceHandler),用Message将Intent携带发送出去。
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
以为ServiceHandler此时绑定的是HandlerThread线程中的Looper,所以ServiceHandler的handleMessage()
是在HandlerThread线程中执行的,
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
这样我们继承IntentService后重写了onHandleIntent(Intent intent)
便可以根据Intent的值做相应的处理,此方法是执行在子线程的。