標籤:
原文地址:http://android.xsoftlab.net/training/run-background-service/index.html
引言
除非特別指定,否則所有的操作都是在UI線程中執行的。不過這會引起問題,因為長時間的耗時操作會妨礙UI線程的運行。這會惹惱使用者,並可能會引起系統錯誤。為了避免這樣的情況出現,Android為此提供了一些類,可以使這些耗時操作放在單獨的線程中執行。這裡用到最多的就是IntentService了。
這節課主要學習如何?IntentService,以及如何向它發送工作請求,以及如何響應它的執行結果。
建立後台服務
IntentService提供了一個非常簡單的構造方法。IntentService允許執行耗時操作,而又不會引起UI線程的阻塞。同樣的,IntentService還不受UI生命週期的影響。所以它可以在一個單獨的環境中持續運行。
不過IntentService也是有限制的,列舉如下:
- 它不可以與UI線程直接互動。為了將結果遞送到UI,不得不採用廣播的形式將結果發送出去。
- 工作請求是按順序執行的。如果目前已經有一個操作在IntentService中執行,那麼再往其中發送操作請求的話,這些操作請求都將會等待,直至第一個操作完成。
- IntentService中的操作不可以被中斷。
不管怎樣,大多數情況下,IntentService是執行後台操作的首選方式。
這節課主要學習如何?IntentService,以及如何建立請求回調方法onHandleIntent(),最後我們還會學習如何在資訊清單檔中聲明該IntentService。
建立IntentService
首先需要建立一個類並繼承IntentService,然後重寫它的onHandleIntent()方法:
public class RSSPullService extends IntentService { @Override protected void onHandleIntent(Intent workIntent) { // Gets data from the incoming Intent String dataString = workIntent.getDataString(); ... // Do work here, based on the contents of dataString ... }}
這裡要注意普通Service的那些回調方法,比如onStartCommand()方法,它會被IntentService自動調用,所以在IntentService內部最好不要重寫這些方法。
在資訊清單檔中聲明IntentService
IntentService同樣需要在資訊清單檔中定義。它的定義方式與普通Service是一樣的。
<application android:icon="@drawable/icon" android:label="@string/app_name"> ... <!-- Because android:exported is set to "false", the service is only available to this app. --> <service android:name=".RSSPullService" android:exported="false"/> ... <application/>
其中android:name屬性說明了IntentService的類名。
這裡要注意:Service標籤內並沒有包含Intent Filter。因為其它組件是通過顯示Intent發送工作請求的。所以這裡不需要定義Intent Filter。這也意味著只有相關組件內的APP或者擁有相同使用者ID的程式才可以訪問該服務。
現在我們已經定義好了一個IntentService類,接下來就可以通過Intent對象向其發送工作請求了。關於如何構建相關對象以及如何發送請求到IntentService的相關內容將會在下節課學習。
Android官方開發文檔Training系列課程中文版:後台服務之IntentService的建立