前言:前面寫了Handler的源碼理解,關於Handler在咱們Android開發中是處處能見到的異步通訊方式。那麼,在Android原生裏,有那些也有到了Handler機制的呢?有不少,好比咱們今天所要理解分析的IntentService就使用到了Handler。接下來,咱們來深刻了解一下。html
HandlerThread:android
IntentService使用到了Handler+HandlerThread構建的帶有消息循環的異步任務處理機制,咱們先簡單看一下HandlerThread是如何工做的吧。併發
HandlerThread的使用步驟:app
// 建立HandlerThread實例 HandlerThread handlerThread = new HandlerThread("handlerThread"); // 啓動HandlerThread線程 handlerThread.start(); // 構建消息循環處理機制 Handler handler = new Handler(handlerThread.getLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message msg) { return false; } });
以上三步的順序不能亂,必須嚴格按照步驟來。第三步是將HandlerThread對象中的looper對象做爲Handler第一個參數,咱們由前面的Handler解析可知道,咱們指定了Looper對象,那咱們的handler的線程looper對象就不用新建,而是使用當前傳入的線程的looper對象。異步
第一步,建立HandlerThread對象,HandlerThread咱們能看到,它繼承自Thread,它有兩個構造函數ide
public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; }
public HandlerThread(String name, int priority) { super(name); mPriority = priority; }
兩個構造方法的都須要傳一個任意字符串參數,參數的主要做用就是指定該線程的名稱;第二個構造方法多傳一個優先級參數,不傳則默認第一個構造方法中的Process.THREAD_PRIORITY_DEFAULT,根據需求自行決定便可;函數
第二步,啓動HandlerThread線程,爲何咱們必需要先啓動HandlerThread,咱們來看看run()就明白了oop
@Override public void run() {
// 得到當前線程的id mTid = Process.myTid();
// 準備循環條件 Looper.prepare();
// 持有鎖機制來得到當前線程的Looper對象 synchronized (this) { mLooper = Looper.myLooper();
// 發出通知,當前線程已經建立mLooper對象成功,這裏主要是通知getLooper方法中的wait notifyAll(); }
// 設置當前線程的優先級 Process.setThreadPriority(mPriority);
// 該方法實現體是空的,子類能夠實現該方法,做用就是在線程循環以前作一些準備工做,固然子類也能夠不實現。 onLooperPrepared();
// 啓動loop Looper.loop(); mTid = -1; }
代碼註釋寫的很是清楚了,在run()方法中主要是調用了Looper.prepare()和Loop.loop()構建了一個循環線程;咱們能夠注意一下的是,在loop()循前調用了onLooperPreapared()方法,這個方法可自行實現,作一些線程循環以前的準備工做,這就有了很好的拓展性了;notifyAll()主要是通知getLooper()中的wait,咱們看一下getLooper()方法;ui
public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. // 若是線程已啓動,looper對象爲空,則繼續等待,前面的喚醒就能夠喚醒當前的等待 synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
第三步,構建消息循環機制,該步驟這裏就不詳細說了,前面《Android異步消息處理機制掌握,從源碼瞭解常使用的Handler》看事後就能理解了。this
OK,咱們講了這麼多HandlerThread的分析理解,那麼IntentService的理解就比較容易了,咱們如今來看看IntentService吧;
public IntentService(String name) { super(); mName = name; }
IntentService是繼承自Service的,是啓動一個服務進行異步任務處理的,該服務會在執行完任務後自行終止;IntentService的構造函數很簡單,傳入一個字符串參數,指定線程名稱;
咱們都知道Service服務生命週期是從onCreate方法開始的,首先來看看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); }
很開心,咱們剛剛分析的HandlerThread在這裏出現了。onCreate方法建立了一個循環的工做線程HandlerThread,而後將HandlerThread當前線程的looper對象傳給Handler做爲參數建立一個消息執行者,經過Handler+HandlerThread構建了一個帶有消息循環機制的異步任務處理機制;ServiveHandler是IntentService的一個內部類,繼承Handler;
Service服務第二步生命週期執行onStartCommand方法;
@Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; }
咱們看到該方法僅僅調用了onStart方法,在IntentService的子類中無需重寫該方法,系統會在IntentService接受一個請求開始調用該方法;
@Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); }
該方法就是經過ServiceHandler獲取一個Message對象,將異步消息請求的intent封裝進Message中,併發送給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,在重寫消息處理方法中調用IntentService的onHandleIntent方法,onHandleIntent方法也是咱們使用IntentService須要重寫的方法,在這個咱們進行咱們的異步任務操做。爲何能夠在這裏進行異步任務操做,當異步任務結束後,調用stopSelf方法自動結束該IntentService服務。前面HandlerThread理解後咱們能夠知道這裏的handleMessage是在工做線程中執行的;那這樣咱們就達到了異步任務處理的目的了。
/** * This method is invoked on the worker thread with a request to process. * Only one Intent is processed at a time, but the processing happens on a * worker thread that runs independently from other application logic. * So, if this code takes a long time, it will hold up other requests to * the same IntentService, but it will not hold up anything else. * When all requests have been handled, the IntentService stops itself, * so you should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. * This may be null if the service is being restarted after * its process has gone away; see * {@link android.app.Service#onStartCommand} * for details. */ @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent);
onHandleIntent方法是咱們使用IntentService的時候在子類須要重寫的方法。經過註釋咱們能夠知道,每一次只能處理一個intent意圖請求,當有多個請求時(客戶端屢次調用startCommand方法),其餘intent暫時會被阻塞掛起,直到前面的intent請求處理完成纔會繼續處理下一個intent請求。處理完成請求後,調用stopSelf方法中止當前服務,而後會繼而調用Service的onDestroy生命週期方法,從而達處處理完成任務後,服務銷燬;
public final void stopSelf(int startId) { if (mActivityManager == null) { return; } try { mActivityManager.stopServiceToken( new ComponentName(this, mClassName), mToken, startId); } catch (RemoteException ex) { } }
@Override public void onDestroy() { mServiceLooper.quit(); }
總結:IntentService是一種異步任務處理的方式,繼承自Service,使用IntentService需在子類重寫onHandleIntent方法,進行異步任務。只要當前服務沒有銷燬,客戶端能夠發起多個Intent請求,looper會循環獲取請求,一個接一個地進行處理。