HandlerThread以及IntentService的深入理解
一、HandlerThread
顧名思義:HandlerThread就是可以使用Handler的Thread
所在路徑:frameworks/base/core/java/android/os/HandlerThread.java
其run方法如下:
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
其特殊之處在於:普通Thread在run方法中執行耗時任務,而HandlerThread在內部創建消息隊列,
外界需要通過Handler發送消息的方式,通知HandlerThread執行具體的任務。
二、IntentService
IntentService是一種特殊的Service,可用於執行後臺耗時任務。任務執行完它會自動停止,因爲其是服務的原因,其優先級是要遠高於其他線程。因爲它適合執行高優先級的後臺任務。
IntentService裏面封裝了HandlerThread和Handler,從它的onCreate方法中可以得知。
public void onCreate() {
super.onCreate();
HandlerThread thread =
new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
利用HandlerThread的Looper來構建構建Handler,可得知Handler發送的消息最終會到HandlerThread執行。
每次啓動IntentService,它的onStartCommand都會被調用一次,它會在這個方法裏面處理外界發送過來的Intent,因爲onStartCommand裏面調用了onStart()函數,所以接下來看看onStart方法的實現:
public void onStart(Intent intent,int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
可以得知,在這個方法裏面,只是通過ServiceHandler發送了一條信息。
接下來看看ServiceHandler的實現:
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會對這個消息進行處理,其中這個Intent對象和外界的startService(intent)中的intent內容是完全一致,然後使用stopSelf(int startId)這個函數來停止服務(這個函數會等待所有的消息處理完畢後才終止服務),如果直接使用stopSelf()會立刻停止服務。
IntentService內部則通過消息的方式向HandlerThread請求執行任務,Handler中的Looper是順序處理消息的,這就意味着IntentService也是順序執行後臺任務的,當有多個後臺任務同時存在時,這些後臺任務會按照外界發起的順序排隊執行。
這裏附上IntentService的一個小實例:
public class IntentServiceA extends IntentService {
private static final String TAG = "LocalIntentService";
public LocalIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getStringExtra("task_action");
Log.d(TAG,"receive task :" + action);
if ("com.ryg.action.TASK1".equals(action)) {
Log.d(TAG,"handle task: " + action);
}
}
@Override
public void onDestroy() {
Log.d(TAG,"service destroyed.");
super.onDestroy();
}
}
在onHandleIntent方法中會從參數中解析出後臺任務的標識,即task_action字段所代表的內容,然後根據不同的任務標識來執行具體的後臺任務。
參考《Android開發藝術探索》