HandlerThread以及IntentService的深入理解
一、HandlerThread
顾名思义:HandlerThread就是可以使用Handler的Thread
所在路径:frameworks/base/core/java/android/os/HandlerThread.java
其run方法如下:
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
其特殊之处在于:普通Thread在run方法中执行耗时任务,而HandlerThread在内部创建消息队列,
外界需要通过Handler发送消息的方式,通知HandlerThread执行具体的任务。
二、IntentService
IntentService是一种特殊的Service,可用于执行后台耗时任务。任务执行完它会自动停止,因为其是服务的原因,其优先级是要远高于其他线程。因为它适合执行高优先级的后台任务。
IntentService里面封装了HandlerThread和Handler,从它的onCreate方法中可以得知。
public void onCreate() {
super.onCreate();
HandlerThread thread =
new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
利用HandlerThread的Looper来构建构建Handler,可得知Handler发送的消息最终会到HandlerThread执行。
每次启动IntentService,它的onStartCommand都会被调用一次,它会在这个方法里面处理外界发送过来的Intent,因为onStartCommand里面调用了onStart()函数,所以接下来看看onStart方法的实现:
public void onStart(Intent intent,int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
可以得知,在这个方法里面,只是通过ServiceHandler发送了一条信息。
接下来看看ServiceHandler的实现:
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);
}
}
在这个函数中可以看到,ServiceHandler会对这个消息进行处理,其中这个Intent对象和外界的startService(intent)中的intent内容是完全一致,然后使用stopSelf(int startId)这个函数来停止服务(这个函数会等待所有的消息处理完毕后才终止服务),如果直接使用stopSelf()会立刻停止服务。
IntentService内部则通过消息的方式向HandlerThread请求执行任务,Handler中的Looper是顺序处理消息的,这就意味着IntentService也是顺序执行后台任务的,当有多个后台任务同时存在时,这些后台任务会按照外界发起的顺序排队执行。
这里附上IntentService的一个小实例:
public class IntentServiceA extends IntentService {
private static final String TAG = "LocalIntentService";
public LocalIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getStringExtra("task_action");
Log.d(TAG,"receive task :" + action);
if ("com.ryg.action.TASK1".equals(action)) {
Log.d(TAG,"handle task: " + action);
}
}
@Override
public void onDestroy() {
Log.d(TAG,"service destroyed.");
super.onDestroy();
}
}
在onHandleIntent方法中会从参数中解析出后台任务的标识,即task_action字段所代表的内容,然后根据不同的任务标识来执行具体的后台任务。
参考《Android开发艺术探索》