IntentService原始碼解析
如果此時你對 Service
有些模糊可先簡單瀏覽一下Andriod中各種服務
首先看一下Google給的介紹

官方介紹
IntentService
繼承
Service
。非同步處理請求,可以自己關閉自己。所有的任務由同一個執行緒完成。並且是序列執行的。
作為服務,所以其優先順序比一般的執行緒要高。 IntentService
封裝了 HandleThread
和 handler
。
HandleThread
HandleThread
繼承 Thread
,其實就是個執行緒。不同的是 HandleThread
建立了自己的 looper
。這意味著主執行緒可以給 HandleThread
傳送訊息,讓其處理一些耗時操作。
public class HandlerThread extends Thread {// handlerThread 繼承自Thread類 int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } @Override public void run() {// 覆寫了Thread類的run方法 mTid = Process.myTid(); Looper.prepare();// 獲取一個Looper synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop();// 開啟訊息迴圈 mTid = -1; } }
從原始碼可以看見 HandleThread
呼叫了 looper.loop()
,這是個無線迴圈來處理隨時可能收到的訊息。所以當我們退出的時候應該呼叫 HandleThread.quit()
或者 HandleThread.stopSefely()
來終止執行緒的執行。
onCreate
原始碼
public void onCreate(){ super.onCreate(); HandleThread thread = new HandleThread("IntentService[" + mName + " ] "); // HandleThread 繼承於Thread,前面說過 thread.start(); mServiceLooper = thread.getLooper(); // 獲取HandleThread中的訊息佇列 mServiceHandler = new ServiceHandler(mServiceLooper); // 用這個訊息佇列初始化一個郵遞員Handler }
執行 onCreate
,初始化 HandleThread
和 Handler
物件。讓Handler能給HandleThread執行緒傳送訊息。
onStartCommand
按照服務的執行生命週期,執行完 onCreate
初始化之後。每次啟動 IntentService
就會執行一次 onStartCommand
,這個方法處理每次外界傳送的 Intent
。 onStartCommand
呼叫了 onStart
。
public void onStart(Intent intent, int startId){ Message msg = mServiceHandler.obtainMessage(); // 從訊息池中拿來msg,不用去new,效率更高 msg.arg1 = strartId; msg.obj = intent; // 用於傳遞資訊 mServiceHandler.sendMessage(msg); }
這裡還使用了 ServiceHandler
,它是 IntentService
的內部類,繼承於 Handler
,原始碼如下
private final class ServiceHandler extends Handler{ public ServiceHandler(Looper looper){ super(looper); } @override public void handleMessage(Message msg){ onHandleIntent((Intent) msg.obj);// 呼叫IntentService處理訊息 stopSelf(msg.arg1);// 等待任務完成之後,停止服務 } }
從上面的原始碼可以得知, ServiceHandler
擁有子執行緒的 looper
。它可以向子執行緒中傳送訊息,子執行緒收到訊息之後呼叫 Handler.handleMessage()
方法處理訊息。所以最終訊息的處理是在子執行緒中完成的!!!
需要注意的是, IntentService
的內部實現是 Looper
, Looper
是順序處理事件的,所以 IntentService
也是順序處理任務的。
驗證一下
public class MyIntentService extends IntentService { private static final String name = "MyIntentService"; public MyIntentService(){ super(name); } @Override protected void onHandleIntent(@Nullable Intent intent) { // 處理耗時操作,已近開起來新的執行緒 long id = Thread.currentThread().getId(); try{ Thread.sleep(3000); }catch (Exception e){ e.printStackTrace(); } Log.d("Service", "當前執行緒"+id); } @Override public void onDestroy() { super.onDestroy(); Log.d("Service","destroy"); } }
// 開啟三個任務 startService(new Intent(this,MyIntentService.class)); startService(new Intent(this,MyIntentService.class)); startService(new Intent(this,MyIntentService.class));

驗證任務執行的順序,以及執行緒號
開啟了三個任務給 IntentService
,可以看見完成的時間剛好差三秒,證明任務執行的順序是序列的。另外可以看見三個任務也都是在子執行緒上完成的。 Thread id = 1
是UI主執行緒。任務執行完成之後自動呼叫了 destroy
。