看其结构:
public abstract class IntentService extends Service{
...
}
抽象类,该类继承自Service,子类需要实现的抽象方法为:
protected abstract void onHandleIntent(Intent intent);
对该方法,有两个问题:
通过搜索IntentService类在该类内部实现了一个内部类ServiceHandler
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
,并在hanldeMessage(Message msg)
方法中调用onHandleIntent(Intent intent)
并通过stopSelf(int startId)
方法终止该Service。
经过测试,在调用
stopSelf(int startId)
去终结最近一个启动的Service时将会将Service销毁(调用到onDestroy()方法)。startId
从1开始逐一增长,最大的ServiceId代表最近被start的service。以下为测试代码和Log结果:
@Override
public int onStartCommand(Intent intent, int flags, final int startId) {
Log.e(TAG,"onStartCommand");
Log.e(TAG,"intent:"+intent+" ,flags:"+flags+" ,startId:"+startId);
//测试stopSelf(int starId)是否能停止特定的startId对应的Service
//结果:能,但是当停止最近启动的ServiceId时将会销毁整个Service
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
Log.e(TAG,"启动的startId为:"+startId);
stopSelf(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
也就是说IntentService在处理完onHanldeIntent()
方法之后就销毁了。我看网上很多文章都说多次启动IntentService不会创建新的服务和新的线程,而实际上这是错误的理解。因为每次在调用完onHanleIntent方法之后该Service就已经被销毁,多次启动将会多次调用Service的onCreate方法去重新初始化Service。那就意味着我们在处理多任务时需要在onHandleIntent()
方法中自定义队列或者循环去发送事件。
那么以上我们了解了处理事件的方法onHandleIntent(Intent intent)
是在handler类中进行调用,那么发送这个Message的handler绑定了哪个线程,又是在哪里进行发送的呢?
我们找到ServiceHandler的对象mServiceHandler
,可以看到它是在Service类中的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并启动该线程
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
//初始化mServiceHandler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
在HandlerThread中初始化了该Thread对应的Looper,mServiceHandler对象通过该Looper绑定该HandlerThread作为工作线程将需要工作的内容发送到handleMessage()
方法中进行处理,这就是为什么说IntentService能够异步处理数据,且不需要在处理耗时任务时自定义线程去处理。
我们知道通过startService启动Service调用的生命周期是onCreate->onStartCommand->onDestroy,而发送工作内容的代码就是在IntentService的onStartCommand方法中调用onStart方法实现(现在onStart()方法已被标记为弃用):
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
很普通的通过hanlder发送消息的代码,将intent封装到message.obj中发送到Handler的实现类ServiceHandler中去处理。
由此我们可以看到,onHandleIntent(Intent intent)
方法中的intent参数就是onStartCommand中的Intent参数,也就是我们通过starService启动的Intent参数,而每次我们通过startService方法启动IntentService实现类就和启动普通的Service类一样,调用到onStartCommand生命周期方法,然后在该方法中通过handler发送Intent到handleMessage方法中进行处理,最后在handleMessage()方法中调用抽象方法onHandleIntent(Intent intent)方法,该方法在IntentService类中暴露给用户去实现。
观察到IntentService在销毁Service时调用了Looper.quit()方法。
@Override
public void onDestroy() {
mServiceLooper.quit();
}
很好地实现了对Looper生命周期的设计,很多时候我们会忘记这些细节,而HandlerThread中绑定并启动Looper的代码在HandlerThread的run()方法中实现,一个标准的启动Looper代码:
@Override
public void run() {
mTid = Process.myTid();
//初始化Looper对象,初始化MessageQueue对象,关联当前线程
Looper.prepare();
synchronized (this) {
//获取当前线程绑定的Looper
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
//HandlerThread类中留给子类去实现的空方法,目的是为了让子类做一些在Looper开始loop前的工作
onLooperPrepared();
//开启loop无限循环作业,处理MessageQueue中存储的的message
Looper.loop();
mTid = -1;
}