概述
IntentService
适用于执行单次的异步的耗时操作,用完会自动销毁服务,本质上是Service
内部封装了HandlerThread
的异步消息处理机制,理解了HandlerThread
的原理才能理解IntentService
。
关于HandlerThread
的介绍:HandlerThread的使用及原理浅析
使用
首先创建一个IntentService
的实现类,在其中模拟耗时操作:
public class TestIntentService extends IntentService {
public TestIntentService() {
//传入的线程名字
super("TestIntentService");
}
//必须实现的处理方法,该方法在子线程执行
@Override
protected void onHandleIntent(@Nullable Intent intent) {
try {
Log.d("test","当前的执行线程为 "+Thread.currentThread().getName());
//模拟耗时操作
Log.d("test","开始耗时操作");
Thread.sleep(1000);
Log.d("test","结束耗时操作");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//IntentService销毁时调用
@Override
public void onDestroy() {
super.onDestroy();
Log.d("test","异步任务结束");
}
}
比如在Activity
中进行调用:
startService(new Intent(MainActivity.this,TestIntentService.class));
当然可以在 Intent中传递一些必要的数据,这里省略了。
运行观察控制台输出:
08-02 16:43:21.282 11381-11474/com.franky.test D/test: 当前的执行线程为 IntentService[TestIntentService]
08-02 16:43:21.283 11381-11474/com.franky.test D/test: 开始耗时操作
08-02 16:43:22.283 11381-11474/com.franky.test D/test: 结束耗时操作
08-02 16:43:22.285 11381-11381/com.franky.test D/test: 异步任务结束
可以清晰地看到任务是在子线程执行的,并且任务执行完毕后,IntentService
自动销毁。
原理
IntentService
的代码比较简单,贴出整个实现:
public abstract class IntentService extends Service {
//子线程的Looper
private volatile Looper mServiceLooper;
//消息处理使用的Handler
private volatile ServiceHandler mServiceHandler;
//线程名
private String mName;
//Service如果没处理完任务之前被杀死,设置为true,那么Service恢复后
//将处理最后一个传进来的Intent
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);
//处理完后自行结束服务
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;//传递的线程名字
}
//Service如果没处理完任务之前被杀死,设置为true,那么Service恢复后
//将处理最后一个传进来的Intent,fasle的话不会恢复最后的Intent
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
//首先创建一个HandlerThread对象
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//获取HandlerThread的Looper,该Looper工作在子线程
mServiceLooper = thread.getLooper();
//使用这个Looper来创建Handler,所以handleMessage同样工作在子线程
mServiceHandler = new ServiceHandler(mServiceLooper);
}
//onStartCommand中调用了该方法
@Override
public void onStart(@Nullable Intent intent, int startId) {
//生成一个Message对象
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
//封装好intent
msg.obj = intent;
//发送Message
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
//这里调用onStart方法
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();//结束子线程的Looper
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
//该方法工作在子线程,但是同一个IntentService对象,在多处调用startService方法启
//动的时候,该方法只能一次处理一个Intent的请求,其他请求暂停,直到所有Intent的请求
//执行完毕后,InentService才会停止。
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
整个的调用流程如下:
- 启动服务:
startService
; IntentService
调用onCreate()
方法创建HandlerThread
对象,和Handler
对象;IntentService
调用onStart()
方法,创建Message
对象并使用Handler
发送;Looper
机制取出Message
分发给Handler
;Handler
调用handleMessage()
方法,回调onHandleIntent()
方法;onHandleIntent()
执行完毕,调用stopSelf()
结束服务;
总结
IntentServiec
通过Service
包装HandlerThread
机制,使其具有异步消息处理的能力,其实对于IntentServiec
主要还是要理解HandlerThread
的处理机制。