IntentService 是一種特殊的 Service,它繼承了 Service 并且它是一個(gè)抽象類,因此必須創(chuàng)建它的子類才能使用 IntentService瘫俊。IntentService 可用于執(zhí)行后臺(tái)耗時(shí)的任務(wù)峦失,當(dāng)任務(wù)執(zhí)行結(jié)束后它會(huì)自動(dòng)停止,同時(shí)由于 IntentService 是服務(wù)的原因筒严,這導(dǎo)致它的優(yōu)先級比單純的線程要高很多丹泉,所以 IntentService 比較適合執(zhí)行一些高優(yōu)先級的后臺(tái)任務(wù),因?yàn)樗鼉?yōu)先級高不容易被系統(tǒng)殺死鸭蛙。
一摹恨、源碼剖析
1. IntentService 是 Service 的子類,所以 IntentService 也是一個(gè)服務(wù)
public abstract class IntentService extends Service {
······
}
2. IntentService 內(nèi)部會(huì)創(chuàng)建 HandlerThread 和 Handler 實(shí)例娶视,并將 HandlerThread 內(nèi)的 Looper 作為 Handler 的 Looper晒哄,服務(wù)銷毀時(shí)退出 Looper
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
3. 外部發(fā)送的事件會(huì)被依次傳遞到 Handler 中
@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;
}
4. 在 Handler 內(nèi)會(huì)調(diào)用 onHandleIntent 方法
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);
}
}
當(dāng) onHandleIntent 方法執(zhí)行結(jié)束后,IntentService 會(huì)通過 stopSelf(int startId) 方法來嘗試停止服務(wù)肪获。這里之所以采用 stopSelf(int startId) 而不是 stopSelf() 來停止服務(wù)寝凌,那是因?yàn)?stopSelf() 會(huì)立刻停止服務(wù),而這個(gè)時(shí)候可能還有其他消息未處理孝赫,stopSelf(int startId) 則會(huì)等待所有的消息都處理完畢后才終止服務(wù)较木。一般來說,stopSelf(int startId) 在嘗試停止服務(wù)之前會(huì)判斷最近啟動(dòng)服務(wù)的次數(shù)是否和 startId 相等青柄,如果相等就立刻停止服務(wù)伐债,不相等則不停止服務(wù)预侯,這個(gè)策略可以從 AMS 的 stopServiceToken 方法的實(shí)現(xiàn)中找到依據(jù)。
二泳赋、使用案例
1. 繼承 IntentService
public class LocalIntentService extends IntentService {
private static final String TAG = "LocalIntentService";
public LocalIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getStringExtra("task_action");
Log.d(TAG, "handle task: " + action);
SystemClock.sleep(2000);
}
@Override
public void onDestroy() {
Log.d(TAG, "service destroyed");
super.onDestroy();
}
}
2. 調(diào)用
Intent service = new Intent(this, LocalIntentService.class);
service.putExtra("task_action", "TASK1");
startService(service);
service.putExtra("task_action","TASK2");
startService(service);
Log 日志:
2020-12-08 13:18:43.606 D/LocalIntentService: handle task: TASK1
2020-12-08 13:18:45.606 D/LocalIntentService: handle task: TASK2
2020-12-08 13:18:47.608 D/LocalIntentService: service destroyed