IntentService
IntentService 是一种特殊的Service,它是继承了Service的抽象类, 因此在使用它的时候,需要先创建它的子类。它通常用于执行一些高优先级的后台任务,并且当任务执行结束后它会自动停止。在实现上,它封装了 HandlerThread 和 Handler。
HandlerThread
它是Thread的子类,是一种可以使用Handler的Thread。具体实现就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。如下:
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
使用方法
使用IntentService处理后台任务也十分方便,只用创建其子类,重写 onHandleIntent 方法即可,然后就是通过startService来启动该服务。(当然别忘了在AndroidManifest中注册服务)这里的后台任务就简单的输出一条日志:
public class LocalIntentService extends IntentService {
private static final String TAG = "LocalIntentService";
public LocalIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String action = intent.getStringExtra("task_action");
if("TASK1".equals(action))
Log.d(TAG, "handle task: " + action);
}
}
Intent service = new Intent(this,LocalIntentService.class);
service.putExtra("task_action","TASK1");
startService(service);
工作原理
先从IntentService的 onCreate 方法看起
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
可以看到,在创建IntentService的时候,它会先创建一个 HandlerThread 然后通过这个线程的Looper来构造一个 Handler 对象 mServiceHandler,这样通过 mServiceHandler 发送的消息最终都会在 HandlerThread 中执行。
然后再看onStartCommand方法,其中会调用 onStart,实现如下:
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
可以看到 IntentService 这里仅仅通过 mServiceHandler 发送了一条 Message,这个消息会在 HandlerThread 中被处理。mServiceHandler 收到消息后,会将 Intent 对象传递给 onHandleIntent 方法去处理。当其处理完毕后,便会停止服务。
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);
}
}