Android 線程簡單分析(一) Android 併發之synchronized鎖住的是代碼仍是對象(二) Android 併發之CountDownLatch、CyclicBarrier的簡單應用(三) Android 併發HashMap和ConcurrentHashMap的簡單應用(四)(待發布) Android 併發之Lock、ReadWriteLock和Condition的簡單應用(五) Android 併發之CAS(原子操做)簡單介紹(六) Android 併發Kotlin協程的重要性(七)(待發布) Android 併發之AsyncTask原理分析(八) Android 併發之Handler、Looper、MessageQueue和ThreadLocal消息機制原理分析(九) Android 併發之HandlerThread和IntentService原理分析(十)併發
首先HandlerThread是一個線程而不是Handler,爲了講解HandlerThread,因此不得不提Looper輪訓器,若是看過Handler源碼的同窗應該很清楚,Handler 發送消息到Looper的MessageQueue中,而後Looper的loop方中不斷輪訓的從MessageQueue中取出消息,並分發給Handler處理,即loop方法在那個線程調用,那麼消息的處理就在那個險種中:ide
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
//沒有消息代表消息隊列正在退出。
return;
}
//消息分發,Message的target持有指定Handler的的引用,分發給指定的Handler處理消息
msg.target.dispatchMessage(msg);
//回收message並放入消息池中
msg.recycleUnchecked();
}
複製代碼
明白的Looper的做用以後,接下看看HandlerThread,應該很好理解,HandlerThread繼承Thread,不是一個Handler,其封裝了Handler、Thread,官方是這樣解析這個類,一個很方便的用於啓動一個具備Looper的新線程。 而後能夠使用這個Looper建立Handler類。必需要先調用start方法:oop
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();//喚醒等待的線程
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// 若是線程已經啓動,一直等待知道Looper被建立。
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
複製代碼
這兩個就是主要的代碼,因此我前面說了,必需要調用start方法啓動線程,在run方法中建立Looper,這樣咱們若是須要在子線程中處理消息,能夠使用這個Looper來建立Handler, getLooper()方法就是拿到HandlerThread的建立Looper;ui
###IntentService:this
講完HandlerThread,必然就是IntentService了,其也是一個Service,只是其在工做線程中運行,可是他是每次提交任務,也是在同一個線程中串行執行,IntentService其分裝了HandlerThread,並使用HandlerThread的Looper做爲處理消息的線程:spa
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
複製代碼
在Oncreate生命週期方法中建立了HandlerThread ,並使用期Looper建立ServiceHandler,service的聲明週期是:首次建立會調用oncreate方法,以後都會調用onStartCommand->onStart因此:線程
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
複製代碼
每次啓動IntentService都會調用mServiceHandler.sendMessage(msg);發消息,並在handler處理消息,因此這些消息都是串行執行的:code
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);
}
}
複製代碼
當onHandleIntent方法執行結束以後,IntentService會嘗試經過stopSelf(int startId)來嘗試中止服務。之因此不用stopSelf()來中止服務,是由於stopSelf()會馬上中止服務,而stopSelf(int startId)則會等待全部的消息都處理完畢纔回終止服務。通常來講,stopSelf(int startId)在嘗試中止服務以前會判斷最近啓動服務的次數是否和startId相等,若是相等則馬上中止服務。協程
若是服務中止,會把全部的消息清除對象
@Override
public void onDestroy() {
mServiceLooper.quit();
}
複製代碼
爲何不建議經過 bindService() 啓動 IntentService?
固然若是你要是同時使用startService()啓動服務、BindService()綁定服務的生命週期,那我就無話可說了,我是以爲可行,具體需求我沒用過,若是哪位同窗有這種需求,能夠討論哦。