IntentService是一种特殊的Service,它继承了Service,是一个抽象类。
普通的Service与它所在的应用处于同一个进程,Service也不是一条新的线程,所以不可以在Service中直接处理耗时的任务。
IntentService使用单独的线程来处理任务,可以用来处理耗时任务,任务执行后会自动停止。而且由于是服务的原因,所以比单独的线程优先级高,不容易被杀死。
IntentService对onBind()和onStartCommand()方法提供了默认实现,要实现一个IntentService,只需要重写onHandleIntent()方法,在方法中处理任务
自定义类继承IntentService
public class IntentServiceInstance extends IntentService {
public static final String TAG = "IntentServiceInstance";
public IntentServiceInstance() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
int sleepTime = Integer.parseInt(intent.getStringExtra("sleepTime"));
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, "Task completed");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(TAG, "Service destroyed");
}
}
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, IntentServiceInstance.class);
intent.putExtra("sleepTime", "20000");
startService(intent);
intent.putExtra("sleepTime", "20000");
startService(intent);
intent.putExtra("sleepTime", "20000");
startService(intent);
}
}
在Activity中启动了3次IntentService,每个任务等待了20秒,运行程序
3个任务是按次序执行的,执行完最后一个任务后,Service自动销毁
下面从源码的角度分析IntentService中处理耗时操作的流程
从IntentService的onCreate()方法分析
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
启动IntentService时,会调用onCreate()方法实创建一个实例,在onCreate()方法中创建了一个HandlerThread,然后使用HandlerThread的Looper构造了一个mServiceHandler 对象,这样通过mServiceHandler发送的消息都会在HandlerThread中执行
每次启动IntentService,都会调用一次onStartCommand()方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
onStartCommand()中调用了onStart()
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
onStart()方法中通过mServiceHandler向HandlerThread中发送了一个消息,消息中的intent内容和startService()中的intent内容是一样的,这样,消息到了HandlerThread中,看一下HandlerThread是怎么处理消息的
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);
}
}
Handler解析消息后转为Intent类型,放到onHandleIntent中去处理,onHandleIntent方法是抽象方法,所以需要重写该方法实现处理的逻辑。onHandleIntent处理完以后,IntentService会调用stopSelf()来停止服务
这样一来,IntentService处理任务的流程就很清楚了,客户端调用startService启动Service后,在IntentService中将Intent内容通过Handler发送到一个HandlerThread中进行处理,onHandleIntent就是在一个Thread中执行的,所以在IntentService中可以处理耗时任务。
由于IntentService内部是通过消息向HandlerThread请求执行任务,Handler的Looper是顺序处理消息的,所以IntentService也是按次序执行任务的。