概述
前面分析了HandlerThread源碼赊淑,下面按照順序分析IntentService的源碼,IntentService是自己維護了一個線程钾挟,來執(zhí)行耗時的操作掺出,然后里面封裝了HandlerThread,能夠方便在子線程創(chuàng)建Handler双抽。
正文
注釋
IntentService is a base class for {@link Service}s that handle asynchronous
requests (expressed as {@link Intent}s) on demand. Clients send requests
through {@link android.content.Context#startService(Intent)} calls; the
service is started as needed, handles each Intent in turn using a worker
thread, and stops itself when it runs out of work.
IntentService是繼承自Service用來處理異步請求的一個基類闲礼,客戶端startService發(fā)送請求,IntentService就被啟動,然后會在一個工作線程中處理傳遞過來的Intent聂抢,當任務(wù)結(jié)束后就會自動停止服務(wù)棠众。
This "work queue processor" pattern is commonly used to offload tasks
from an application's main thread. The IntentService class exists to
simplify this pattern and take care of the mechanics. To use it, extend
IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
will receive the Intents, launch a worker thread, and stop the service as appropriate
工作器處理模式通常用來加載應(yīng)用主線程的耗時任務(wù),IntentService用來簡化這種模式并且專注于耗時任務(wù)的處理空盼。使用IntentService揽趾,需要繼承IntentService并且復(fù)寫onHandleIntent方法。IntentService在接收到一系列Intent之后篱瞎,啟動一個子線程痒芝,然后合適的實際關(guān)閉Service。
All requests are handled on a single worker thread -- they may take as
long as necessary (and will not block the application's main loop), but
only one request will be processed at a time.
所有的請求都是都是在同一個子線程中進行處理的—他們可能會花費很長時間(并不會阻塞應(yīng)用的loop線程)澄者,但是在同一時刻IntentService只能處理一個請求粱挡。
通過注釋俄精,已經(jīng)將IntentService的使用方式嘀倒,使用場景描述地相當清楚局冰,不再多解釋康二,相比較我們自己在Intent中開啟線程處理耗時任務(wù)勇蝙,IntentService不需要我們自己去關(guān)閉Service,它自己會在任務(wù)完成之后自行關(guān)閉产雹,不過每次只能處理一個任務(wù)翁锡,所以不適用于高并發(fā)馆衔,適用于請求數(shù)較少的情況,類似于APP的版本檢測更新拷获,后臺定位功能以及讀取少量的IO操作匆瓜。
成員變量
private volatile Looper mServiceLooper;//子線程中的Looper
private volatile ServiceHandler mServiceHandler;//內(nèi)部持有的一個Handler
private String mName;//內(nèi)部創(chuàng)建的線程名字
private boolean mRedelivery;//服務(wù)被異常終止后重新創(chuàng)建調(diào)用onStartCommand是否回傳Intent
ServiceHandler
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//子線程中回調(diào)Intent
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
內(nèi)部創(chuàng)建了一個ServiceHandler陕壹,然后將傳遞過來的Intent封裝成一個Message糠馆,然后再將Message封裝成一個Intent怎憋,回調(diào)onHandleIntent,其實轉(zhuǎn)換的目的就是講主線程的Intent切換到子線程中去執(zhí)行了而已毕匀。
構(gòu)造方法
//工作線程的名字
public IntentService(String name) {
super();
mName = name;
}
onCreate
@Override
public void onCreate() {
super.onCreate();
//創(chuàng)建HandlerThread
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
//開啟線程創(chuàng)建子線程Looper
thread.start();
//獲取子線程Looper
mServiceLooper = thread.getLooper();
//創(chuàng)建子線程Handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
onStartCommand
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
//調(diào)用onStart方法
onStart(intent, startId);
//根據(jù)mRedelivery的值來確定返回重傳Intent的黏性廣播還是非黏性廣播
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
onStart
@Override
public void onStart(@Nullable Intent intent, int startId) {
//創(chuàng)建一個Message
Message msg = mServiceHandler.obtainMessage();
//消息標志皂岔,作為當前Service的標志
msg.arg1 = startId;
//攜帶Intent
msg.obj = intent;
//發(fā)送消息躁垛,此時將線程切換到子線程
mServiceHandler.sendMessage(msg);
}
@Override
public void handleMessage(Message msg) {
//處理發(fā)送過來的消息,在子線程
onHandleIntent((Intent)msg.obj);
//處理完消息之后停止Service
stopSelf(msg.arg1);
}
onDestroy
@Override
public void onDestroy() {
//退出Looper
mServiceLooper.quit();
}
使用方式
IntentService intentService = new IntentService("main") {
@Override
protected void onHandleIntent(Intent intent) {
// 處理耗時操作
}
};
//不需要關(guān)注Service的生命周期,IntentService會自行處理
總結(jié)
IntentService實際上內(nèi)部實例化了一個HandlerThread,并且封裝了一個Handler逊谋,所以他的工作流程通過上面的源碼胶滋,分析如下:
- 創(chuàng)建一個HandlerThread,開啟HandlerThread來創(chuàng)建Looper
- 創(chuàng)建一個Handler,傳入Looper,從而在子線程實例化Handler
- 在onStartCommand中獲取到的Intent作為消息的obj發(fā)送出去
- 然后在onHandleIntent中處理這個消息究恤,注意此時是在子線程
- 跟HandlerThread一樣,IntentService內(nèi)部是采用Handler來實現(xiàn)的部宿,所以任務(wù)是串行執(zhí)行的窟赏,不適用于大量耗時操作箱季。