在Android基礎知識:多線程基礎總結中除了AsyncTask
和HandlerThread
還提到了Android
提供的另一種進行異步任務的方式IntentService
。這一篇就來看看IntentService
的使用和運行原理。android
IntentService
的使用步驟分爲如下幾步:bash
1.繼承實現IntentService抽象類,複寫onHandleIntent方法markdown
public class MyIntentService extends IntentService { private static final String TAG = "MyIntentService"; private int percent; public MyIntentService() { super("MyIntentServiceThread"); } @Override protected void onHandleIntent(Intent intent) { String type = intent.getStringExtra("type"); switch (type) { case "type1": { for (percent = 0; percent <= 100; percent += 10) { try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } Log.d(TAG, Thread.currentThread().getName() + " type1 " + percent + "% progress"); } Log.d(TAG, Thread.currentThread().getName() + ":finish"); } break; } } } 複製代碼
2.在AndroidManifest.xml註冊Service多線程
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.thread.intentservice"> <application ....... <service android:name=".MyIntentService" /> </application> </manifest> 複製代碼
3.啓動IntentService服務app
Intent intent = new Intent(this, MyIntentService.class); intent.putExtra("type", "type1"); startService(intent); 複製代碼
運行結果: 異步
從使用方法上來看IntentService
與通常的Service
使用步驟也沒啥區別,都是先建立實現一個Service
再到AndroidManifest.xml
中註冊,最後啓動服務便可。那麼仍是從源碼看看IntentService
到底有什麼特別的地方。ide
public abstract class IntentService extends Service { ....... /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public IntentService(String name) { super(); mName = name; } 複製代碼
首先看到IntentService
是個抽象類,而且繼承自Service
,它的構造函數中只傳入了name
,從註釋看出就是工做線程的name
。既然是個Service
接着就看它生命週期中的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 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); // 調用HandlerThread的start方法開啓線程 thread.start(); // 得到HandlerThread中的Looper mServiceLooper = thread.getLooper(); // 建立Handler mServiceHandler = new ServiceHandler(mServiceLooper); } 複製代碼
onCreate
方法中的代碼看着有些熟悉就是以前在Android進階知識:HandlerThread相關中提到的HandlerThread
的使用步驟。因此說在onCreate
方法中就是建立了一個HandlerThread
的工做線程,調用了它的start
方法而且建立了對應Handler
。先來看一下這個ServiceHandler
類的實現。oop
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);
}
}
複製代碼
ServiceHandler
是IntentService
的內部類,其實現也很簡單,接收了傳入的Looper
後複寫handleMessage
方法,handleMessage
方法中收到消息後先調用了onHandleIntent
方法將intent
傳入。onHandleIntent
方法是咱們本身實現IntentService
時複寫的方法,源碼這裏是個抽象方法,主要進行異步耗時任務,而後調用stopSelf
將自身關閉。post
protected abstract void onHandleIntent(@Nullable Intent intent);
複製代碼
接着繼續按生命週期走到了onStartCommand
方法。
@Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } 複製代碼
onStartCommand
方法中又調用了onStart
方法,而onStart
方法建立了消息,而且將接收到的intent
做爲消息的obj
,startId
傳遞給消息arg1
,最後調用mServiceHandler.sendMessage
將消息發送出去。到此整個IntentService
的運行流程就差很少了,最後在調用stopSelf
方法後服務會調用生命週期中的onDestory
方法,在IntentService
的onDestory
方法中會直接調用mServiceLooper.quit()
方法將Lopper
退出。
另外IntentService
中還有個mRedelivery
成員變量能夠經過setIntentRedelivery
方法設置,用來決定onStartCommand
方法的返回值,從而決定服務在被異常殺死後是否自動重啓該服務。
// 布爾值變量 private boolean mRedelivery; // setIntentRedelivery方法 public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } // onStartCommand返回值 @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } 複製代碼
從上面的閱讀的源碼能夠知道IntentService
實現異步任務是基於HandlerThread
實現的。
IntentService的運行流程: 啓動服務後會先進行生命週期的onCreate
方法,方法中建立HandlerThread
和ServiceHandler
,接着進入生命週期的onStartCommand
方法,onStartCommand
方法中調用onStart
方法,onStart
方法使用ServiceHandler
發送消息,handleMessage
方法中接收到消息,調用複寫的onHandleIntent
方法,最後調用stopSelf
方法關閉本身。
IntentService與普通Service對比:
普通Service | IntentService |
---|---|
運行在主線程 | 運行在建立的工做線程 |
須要手動調用stopService關閉 | 自動調用stopSelf關閉 |