咱們知道Service是運行在主線程裏的,所以,若是在服務裏面執行耗時代碼操做,咱們須要開啓一個子線程去處理這些代碼。好比咱們能夠在onStartCommand
方法裏面去開啓子線程來處理耗時代碼。java
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(){
@Override
public void run() {
/**
* 耗時的代碼在子線程裏面寫
*/
}
};
thread.start();
return super.onStartCommand(intent, flags, startId);
}
複製代碼
可是,咱們都知道,服務一旦啓動,就會一直運行下去,必須調用stopService()或者stopSelf()方法才能讓服務中止下來。因此,咱們來修改一下run方法android
public void run() {
/**
* 耗時的代碼在子線程裏面寫
*/
stopSelf();
}
}
複製代碼
就這樣,咱們很容易的就在服務裏面開啓了一個線程,而後在代碼最後面加上stopSelf();這樣就能夠在代碼運行結束的時候,結束服務了。可是這樣對於咱們開發者來講,是否是有些麻煩呢,確實有點麻煩,好比你有時候忘記了開啓線程呢?或者忘記了調用stopSelf()?web
因此,谷歌給咱們一個很好的類,經過這個類咱們就能夠不用管這些東西,由於這個類已經幫咱們實現了在子線程中操做代碼了。同時,但子線程代碼執行完畢,這個服務會自動銷燬,不用再佔用內存資源。因此,咱們經過這個類,就能夠不用去開啓線程,也不用去銷燬這個服務。由於,這個類都幫咱們處理好了。這個類就是IntentService。這個類的使用和Service大同小異,可是比Service更加省心,更加方便。下面咱們直接看代碼吧,我習慣在代碼中講解。app
/**
* IntentService是一個以{@linkService}的爲基類來處理異步請求的類
* 客戶端發送請求經過{@link android.content.Context *#startService(Intent)}調用;
* 該服務根據須要啓動,使用worker線程依次處理每一個Intent線程,並在run工做完成時自行中止本service。
*
* <p>這種「工做隊列處理器」模式一般用於卸載任務
*來自應用程序的主線程。 IntentService類存在於
*簡化這種模式並處理機制。要使用它,請擴展
* IntentService並實現{@link #onHandleIntent(Intent)}。 IntentService
* 將接收Intents,啓動工做線程,並中止服務
*合適。
*
* <p>全部請求都在一個工做線程上處理 - 它們能夠做爲
*儘量長(而且不會阻止應用程序的主循環),可是
*一次只能處理一個請求。
*
*/
public abstract class IntentService extends Service {
//開啓線程的Looper
private volatile Looper mServiceLooper;
//用於發送和處理消息的handler
private volatile ServiceHandler mServiceHandler;
//子線程的名稱
private String mName;
//是否可重複發送
private boolean mRedelivery;
//處理消息handler的實現
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//子線程
//抽象方法 留給子類去重寫
onHandleIntent((Intent)msg.obj);
// 子線程任務執行完了,中止本service
stopSelf(msg.arg1);
}
}
/**
* 構造函數
* @param name worker線程的名字 對調試有用
*/
public IntentService(String name) {
super();
mName = name;
}
/**
*
* Sets intent redelivery preferences. Usually called from the constructor
* with your preferred semantics.
* 設置intent重發偏好,一般在構造函數調用
*
*
* 若是設置是true,{@link #onStartCommand(Intent, int, int)} 將返回{@link Service#START_REDELIVER_INTENT}
* 所以,若是這個進程在onHandleIntent返回以前死掉了,那麼進程將會被重啓,而且發送此intent
* 若是多個intents被髮送,只有最近的一個會被確保從新發送
*
* 若是設置爲false,{@link #onStartCommand(Intent, int, int)} 將返回{@link Service#START_NOT_STICKY}
* 若是這個進程死掉了,那麼這個intent就死掉了
*
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
//使用HandlerThread開啓一個線程,併產生looper和消息隊列
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//獲取上述子線程的looper
mServiceLooper = thread.getLooper();
//初始化 handler
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
//onstart時發送一個消息給handle
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
//是否可重複發送
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
/**
* Unless you provide binding for your service, you don't need to implement this
* method, because the default implementation returns null.
* @see android.app.Service#onBind
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 這個方法在子線程中執行,一次只能執行一個事件,
*/
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
複製代碼
總結:使用IntentServices
是使用Service+ HandlerThread
的方式,不少狀況下咱們能夠使用HandlerThread+ handler
來進行線程執行和handler分發消息。less