第11章 Android的線程和線程池
除了Thread以外,在Android中可以扮演線程的角色還有很多,比如AsyncTask和IntentService,同時HandlerThread也是一種特殊的線程。
AsyncTask封裝了線程池和Handler,它主要是爲了方便在子線程中更新UI。HandlerThread是一種具有消息循環的線程,在它的內部可以使用Handler。IntentService是一個服務,IntentService內部採用HandlerThread來執行任務,當任務執行完畢後IntentService會自動退出。IntentService是一種服務,不容易被系統殺死從而可以儘量保證任務的執行,如果是一個後臺線程,由於這個時候進程中沒有活動的四大組件,那麼這個進程的優先級就會降低,容易被系統殺死,這就是IntentService的優點。
11.1 主線程和子線程
從Android3.0開始系統要求網絡訪問必須在子線程執行,否則網絡訪問將會失敗並拋出NetworkOnMainThreadException這個異常。
11.2 Android中的線程形態
11.2.1 AsyncTask
AsyncTask是一種輕量級的異步任務類,它可以在線程池中執行後臺任務,然後把執行的進度和最終結果傳遞給主線程並在主線程中更新UI。
4個核心方法:
- onPreExecute()
- doInBackground(Params… params)在此方法中可以通過publishProgress方法來更新任務進度,publishProgress方法會調用onProgreeUpdate方法。
- onProgressUpdate(Progress…values)
- onPostEcecute(Result result)
- onCancelled(),任務被取消時被調用,onPostExecute()不會被調用
AsyncTask在使用中的一些限制條件:
- AsyncTask的類必須在主線程中加載
- AsyncTask的對象必須在主線程中創建
- execute方法必須在UI線程調用
- 不要直接調用onPreExecute()、onPostExecute、doInBackground、onProgressUpdate方法
- 一個AsyncTask對象只能執行一次,即只能調用一次execute方法
- Android1.6之前,AyncTask是串行執行任務的,Android1.6時AsyncTask開始採用線程池處理並行任務,但是從Android3.0開始,AsyncTask又採用一個線程來串行執行任務。在Android3.0以後的版本中,可以通過AsyncTask的executeOnExecutor方法來並行執行任務。
AsyncTask的工作泳道流程圖:
11.2.3 HandlerThread
HandlerThread繼承了Thread,在run()方法中創建了Looper。
11.2.4 IntentService
IntentService是一種特殊的Service,繼承了Service。可以用來執行耗時任務(在非UI線程執行),當任務執行後它會自動停止。
有兩個停止服務的方法stopSelf()和stopSelf(int startId)。stopSelf()會立刻停止服務,stopSelf(int startId)會等待所有的的消息都處理完畢後才終止服務(原理是判斷最近啓動服務的id是否和startId相等)。
在onHandleIntent方法中處理耗時任務。HandlerThread繼承Handler,所以一樣是順序處理消息,這意味着IntentService也是順序執行後臺任務。