咱们知道Service是运行在主线程里的,所以,若是在服务里面执行耗时代码操做,咱们须要开启一个子线程去处理这些代码。好比咱们能够在onStartCommand
方法里面去开启子线程来处理耗时代码。java
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(){
@Override
public void run() {
/**
* 耗时的代码在子线程里面写
*/
}
};
thread.start();
return super.onStartCommand(intent, flags, startId);
}
复制代码
可是,咱们都知道,服务一旦启动,就会一直运行下去,必须调用stopService()或者stopSelf()方法才能让服务中止下来。因此,咱们来修改一下run方法android
public void run() {
/**
* 耗时的代码在子线程里面写
*/
stopSelf();
}
}
复制代码
就这样,咱们很容易的就在服务里面开启了一个线程,而后在代码最后面加上stopSelf();这样就能够在代码运行结束的时候,结束服务了。可是这样对于咱们开发者来讲,是否是有些麻烦呢,确实有点麻烦,好比你有时候忘记了开启线程呢?或者忘记了调用stopSelf()?web
因此,谷歌给咱们一个很好的类,经过这个类咱们就能够不用管这些东西,由于这个类已经帮咱们实现了在子线程中操做代码了。同时,但子线程代码执行完毕,这个服务会自动销毁,不用再占用内存资源。因此,咱们经过这个类,就能够不用去开启线程,也不用去销毁这个服务。由于,这个类都帮咱们处理好了。这个类就是IntentService。这个类的使用和Service大同小异,可是比Service更加省心,更加方便。下面咱们直接看代码吧,我习惯在代码中讲解。app
/**
* IntentService是一个以{@linkService}的为基类来处理异步请求的类
* 客户端发送请求经过{@link android.content.Context *#startService(Intent)}调用;
* 该服务根据须要启动,使用worker线程依次处理每一个Intent线程,并在run工做完成时自行中止本service。
*
* <p>这种“工做队列处理器”模式一般用于卸载任务
*来自应用程序的主线程。 IntentService类存在于
*简化这种模式并处理机制。要使用它,请扩展
* IntentService并实现{@link #onHandleIntent(Intent)}。 IntentService
* 将接收Intents,启动工做线程,并中止服务
*合适。
*
* <p>全部请求都在一个工做线程上处理 - 它们能够做为
*尽量长(而且不会阻止应用程序的主循环),可是
*一次只能处理一个请求。
*
*/
public abstract class IntentService extends Service {
//开启线程的Looper
private volatile Looper mServiceLooper;
//用于发送和处理消息的handler
private volatile ServiceHandler mServiceHandler;
//子线程的名称
private String mName;
//是否可重复发送
private boolean mRedelivery;
//处理消息handler的实现
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//子线程
//抽象方法 留给子类去重写
onHandleIntent((Intent)msg.obj);
// 子线程任务执行完了,中止本service
stopSelf(msg.arg1);
}
}
/**
* 构造函数
* @param name worker线程的名字 对调试有用
*/
public IntentService(String name) {
super();
mName = name;
}
/**
*
* Sets intent redelivery preferences. Usually called from the constructor
* with your preferred semantics.
* 设置intent重发偏好,一般在构造函数调用
*
*
* 若是设置是true,{@link #onStartCommand(Intent, int, int)} 将返回{@link Service#START_REDELIVER_INTENT}
* 所以,若是这个进程在onHandleIntent返回以前死掉了,那么进程将会被重启,而且发送此intent
* 若是多个intents被发送,只有最近的一个会被确保从新发送
*
* 若是设置为false,{@link #onStartCommand(Intent, int, int)} 将返回{@link Service#START_NOT_STICKY}
* 若是这个进程死掉了,那么这个intent就死掉了
*
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
//使用HandlerThread开启一个线程,并产生looper和消息队列
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//获取上述子线程的looper
mServiceLooper = thread.getLooper();
//初始化 handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
//onstart时发送一个消息给handle
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
//是否可重复发送
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
/**
* Unless you provide binding for your service, you don't need to implement this
* method, because the default implementation returns null.
* @see android.app.Service#onBind
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 这个方法在子线程中执行,一次只能执行一个事件,
*/
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
复制代码
总结:使用IntentServices
是使用Service+ HandlerThread
的方式,不少状况下咱们能够使用HandlerThread+ handler
来进行线程执行和handler分发消息。less