標籤:
1.IntentService用來幹什嗎?
一般情況下,service是在主線程中啟動並執行,這樣如果處理耗時操作會造成ANR的問題,但是很多情境下我們需要用service進行耗時操作,此時就需要一種新的機制,於是便引進了IntentService的概念。
先看一下官方的說法吧
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through 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.
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 onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
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.
總結一下,就是IntentService為了符合下面需求的情境。
2.怎麼實現的上述需求?2.1 非同步處理耗時任務
先看一眼IntentService的成員:
public abstract class IntentService extends Service {private volatile Looper mServiceLooper;private volatile ServiceHandler mServiceHandler;private String mName;private boolean mRedelivery;//......}
從這裡可以看出來IntentService使用handler機制實現了非同步
下面進入它的生命週期
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);}public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg);}public void onDestroy() { mServiceLooper.quit();}
從這裡可以看出,在onCreate中使用HandlerThread的初始化了非同步機制,在onstart方法中擷取到Intent參數,將其放入Message中,
然後就是我上一篇部落格裡寫過的handler使用了,這裡我們來看一看此處定製的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); }}
在之前create方法中可以看到我們調用了建構函式,與當前線程的looper與handler相關聯。
handlerMessage的方法中,我們先調用了onHandlerIntent的方法處理包含Intent的message
protected abstract void onHandleIntent(Intent intent);
當實現IntentService時,需要重寫onHandleInent方法。
2.2 自行停止功能
在執行完處理方法後,調用stopSelf方法,終止了這個Service,stopSelf的方法在其父類service中實現,使用ActivityManager進行stop操作。
因為這裡的serviceHandler與當前的looper相關聯,因此它工作在當前的線程中,每次只處理一個請求,如果後續請求到達該線程,則在訊息佇列中進行阻塞,當所有請求處理完畢後,調用stopSelf方法自行停止。由於這種規定,導致IntentService不適合約時相應多個請求,適合響應例如離線資料下載這種單一的耗時請求。
public final void stopSelf(int startId) { if (mActivityManager == null) { return; } try { mActivityManager.stopServiceToken( new ComponentName(this, mClassName), mToken, startId); } catch (RemoteException ex) { }}
綜上所述,IntentService利用Intent傳遞參數構建Message,然後將該Message通過Handler機制進行處理,實現了非同步處理。處理後調用stopSelf進行自動停止。
這樣的特性可以使我們在service中非同步執行耗時操作,並且自行停止。
?
IntentService源碼分析