IntentService 用完即走
IntentService,可以看做是Service和HandlerThread的結合體,在完成了使命之后會自動停止,適合需要在工作線程處理UI無關任務的場景。
- IntentService 是繼承自 Service 並處理異步請求的一個類,在 IntentService 內有一個工作線程來處理耗時操作。
- 當任務執行完后,IntentService 會自動停止,不需要我們去手動結束。
- 如果啟動 IntentService 多次,那么每一個耗時操作會以工作隊列的方式在 IntentService 的 onHandleIntent 回調方法中執行,依次去執行,使用串行的方式,執行完自動結束。
IntentService繼承自Service,內部有一個HandlerThread對象。
在onCreate的時候會創建一個HandlerThread對象,並啟動線程。緊接着創建ServiceHandler對象,ServiceHandler繼承自Handler,用來處理消息。ServiceHandler將獲取HandlerThread的Looper就可以開始正常工作了。
每啟動一次onStart方法,就會把數消息和數據發給mServiceHandler,相當於發送了一次Message消息給HandlerThread的消息隊列。mServiceHandler會把數據傳個onHandleIntent方法,onHandleIntent是個抽象方法,需要在IntentService實現,所以每次onStart方法之后都會調用我們自己寫的onHandleIntent方法去處理。處理完畢使用stopSelf通知HandlerThread已經處理完畢,HandlerThread繼續觀察消息隊列,如果還有未執行玩的message則繼續執行,否則結束。
啟動 IntentService 為什么不需要新建線程?
IntentService內部的HandlerThread 繼承自 Thread,內部封裝了 Looper,在這里新建線程並啟動,所以啟動 IntentService 不需要新建線程。
為什么不建議通過 bindService() 啟動 IntentService?
@Override public IBinder onBind(Intent intent) { return null; }
IntentService 源碼中的 onBind() 默認返回 null;不適合 bindService() 啟動服務,如果你執意要 bindService() 來啟動 IntentService,可能因為你想通過 Binder 或 Messenger 使得 IntentService 和 Activity 可以通信,這樣那么 onHandleIntent() 不會被回調,相當於在你使用 Service 而不是 IntentService。
為什么多次啟動 IntentService 會順序執行事件,停止服務后,后續的事件得不到執行?
@Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } @Override public void onDestroy() { mServiceLooper.quit(); }
IntentService 中使用的 Handler、Looper、MessageQueue 機制把消息發送到線程中去執行的,所以多次啟動 IntentService 不會重新創建新的服務和新的線程,只是把消息加入消息隊列中等待執行,而如果服務停止,會清除消息隊列中的消息,后續的事件得不到執行。
原文:https://blog.csdn.net/iromkoear/article/details/63252665