在Android基礎知識:多線程基礎總結中除了AsyncTask
和HandlerThread
還提到了Android
提供的另一種進行異步任務的方式IntentService
。這一篇就來看看IntentService
的使用和運行原理。android
IntentService
的使用步驟分爲如下幾步:bash
1.繼承實現IntentService抽象類,複寫onHandleIntent方法多線程
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註冊Serviceapp
<?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服務異步
Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("type", "type1");
startService(intent);
複製代碼
運行結果: ide
從使用方法上來看IntentService
與通常的Service
使用步驟也沒啥區別,都是先建立實現一個Service
再到AndroidManifest.xml
中註冊,最後啓動服務便可。那麼仍是從源碼看看IntentService
到底有什麼特別的地方。函數
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
方法。oop
@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
類的實現。post
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
將自身關閉。ui
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關閉 |