公众号【刘桂林】
今天介绍一下IntentService,他和Service其实差不多,只是内部实现了一个HandlerThread,这点我们看源码其实就可以知道,IntentService的特性如下:
- 启动的方式和正常的Service一致
- 执行完任务之后自动停止
- 多次启动以队列的形式等待执行
使用起来还是比较简单的,来看下我写的这个例子:
public class TaskService extends IntentService {
private static final String TAG = "TaskService";
private ExecutorService service;
public TaskService() {
super("TaskService");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"onCreate");
if (service == null) {
service = Executors.newFixedThreadPool(2);
}
}
@Override
protected void onHandleIntent(Intent intent) {
//通过线程池来执行搜索任务
service.execute(new Runnable() {
@Override
public void run() {
scanSdcardMusic("/mnt/sdcard/");
}
});
}
/**
* 搜索Sdcard中的音乐
*/
private void scanSdcardMusic(String path) {
File file = new File(path);
if (file == null)
return;
File[] files = file.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
//是否是文件夹
if (files[i].isDirectory()) {
scanSdcardMusic(files[i].getPath());
} else {
if (files[i].getName().endsWith(".mp3")) {
Log.i(TAG,"Music:" + files[i].getName());
}
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy");
}
}
来分析一下这段代码,首先是继承IntentService,需要重写onHandleIntent并且需要一个有名字的构造参数,这里我默认写死了一个super(“TaskService”),在onCreate中,我初始化了一个线程池newFixedThreadPool,因为我们的任务是搜索Sdcard上所有的mp3文件,这属于IO操作,所有我们需要放在线程中操作,具体来看下onHandleIntent,在里面开启了一个线程池的任务去搜索sdcard,并且将mp3的名字打印出来,我们看下打印的Log
在Log中我们可以看到搜索完后打印了两个mp3,这个时候任务结束了,则自动停止,走了onDestroy方法,这也很符合他的特性,所以他还是比较满足于一些异步独立的任务,我们来看下他的源码。
源码分析
他的源码比较少,我们来看下:
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
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);
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 + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@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);
来看下他的onCreate入口,他直接就创建了一个HandlerThread并且以传入的name作为线程名称,getLooper的操作为单独的队列,也就对应了他的队列特性,并且初始化了一个Handler,然后在他的onStartCommand中执行了onStart方法,这个方法只是发送了一个消息给Handler,在handleMessage他就更加简单了,直接调用onHandleIntent,接着再调用自身的stopSelf结束任务,可以说IntentService的实现是异常的简单的:总结出一句话:创建线程后发送Handler执行任务后自动停止
就是这么简单,你还有什么疑问吗?
感谢你在百忙之中看我的文章,谢谢!