分析的IntentService原始碼為API-25版本
IntentService屬於Service
IntentService繼承自Service,那麼它的結構就和Service一樣。
這個不需多講。但在使用上與Service有點不同,可以說簡化版的Service。有點類似Handler與AsyTask的關係。
IntentService的使用
Intent serviceIntent = new Intent(this, ParseIntentService.class);
startService(serviceIntent);
複製程式碼
上面程式碼就是開啟一個IntentService服務。開啟之後就不用管理它了。這就是剛才說的簡化版的Service。這篇文章的重點其實就是這裡:IntentService為什麼是簡化的Service
上面的ParseIntentService繼承IntentService,重寫了onHandleIntent()方法。
IntentService原始碼
IntentService的原始碼不多就只有百來行
解析下這裡的程式碼:
出現Looper和Handler。
ServiceHandler handleMessage()方法,呼叫完onHandleIntent();方法後stopSelf()即停止服務。所以上面說IntentService開啟服務後不需要管它,因為它呼叫完ServiceHandler的handleMessage()方法後就會停止服務。
都知道Handler的handleMessage()不是Handler自己呼叫的,是有傳送資訊,handleMessage()就會被呼叫。那麼現在看看哪裡傳送資訊。Looper 在後面涉及到會介紹
IntentService的onCreate()方法
都知道Service和Activity類似都會有相關生命週期的方法。當上門的程式碼開啟服務,系統就會呼叫Service的onCreate()
通過onCreat()方法可以得出下邊的結論:
- HandlerThread 一個執行緒類開啟一個工作執行緒
- mServiceLooper為工作執行緒的Looper
- ServiceHandler為工作執行緒的Handler
首先Handler是主執行緒的Handler還是工作執行緒的Handler主要看它的Looper,而ServiceHandler的Looper為工作執行緒下的Looper,所以ServiceHandler屬於工作執行緒的Handler。判斷哪個執行緒的Handler,主要因為看handlerMessage()方法在哪個執行緒執行。
其次為什麼說mServiceLooper為工作執行緒的Looper,
截圖是HandlerThread的run()方法。可以看到mServiceLooper是在run()裡面得到的,所以mServiceLooper為工作執行緒的Looper.。
HandlerThread 一個執行緒類這個就不用說了。
HandlerThread
該類其實是幹嘛的呢?簡單來說,它就是幫我們建立一個工作執行緒的Looper,Looper的作用就是輪詢我們的訊息分發機制(這裡不細說,細說又是一篇了。。。)。詳細瞭解HandlerThread 可以看下面這篇文章
為什麼要用HandlerThread,怎麼用?
為什麼出現Handler,Looper這些訊息分發類別的類?
主要因為IntentService的onStart()方法中傳送了訊息,上面建立onCreat()時,構建了ServiceHandler物件。通過Handler訊息分發機制,處理抽象方法onHandleIntent();
使用IntentService,重寫onHandleIntent()方法
- 第一,建立一個類繼承IntentService,實現onHandleIntent();
public class ParseIntentService extends IntentService {
public ParseIntentService() {
super("ParseIntentService");
}
/**
* 該方法在工作執行緒上呼叫
* */
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//TODO 需要在服務做的事情
}
});
}
}
複製程式碼
- 第二,建立Intent,呼叫startService()方法。
Intent serviceIntent = new Intent(this, ParseIntentService.class);
startService(serviceIntent);
複製程式碼
總結
- onHandleIntent()方法是在工作執行緒上的;不用執行更新UI的工作
- IntentService裡面已經有工作執行緒無需開啟新的工作執行緒。
這裡想說一下:如果你在onHandleIntent()通過Retrofit呼叫介面,而又使用OkHttp的,建議使用Service不建議用IntentService。因為OkHttp已經幫我們建立了工作執行緒。這樣又用IntentService的工作執行緒又用IntentService實際上是一種記憶體消耗。 - 這點給自己一個筆記通過這個IntentService最主要認識了在工作執行緒中的Handler;HandlerThread管理工作執行緒的Looper