谷歌官方文檔是學習android很好的地方,不過滿篇的英文讓人看着會很吃力,所以我打算將一些文檔翻譯出來,供大家去參考學習。當然本人的英文水平很有限,肯定有很多翻譯不妥的地方,希望見諒。如果要轉載,請註明出處,我會非常感激,並且努力繼續做下去。
概述:
服務是一個應用程序組件,表示當應用程序沒有和用戶交互時想執行一個長時間的操作或者提供功能給其他的應用使用。每一個服務必須有相應的<service>聲明在AndroidManifest.xml中。服務可以通過Context.startService()和Context.bindService()開啓。
注意服務跟其他的應用對象一樣,是運行在其宿主進程的主線程中的。這意味着,如果你的服務打算用來執行任何耗費CPU(如:mp3回訪)或者阻塞操作(如:聯網),那麼應該產生一個子線程來做這些工作。關於進程與線程的更多信息可以在這 Processes and Threads找到。IntentService(意圖服務)作爲一個標準服務的實現類擁有自己的線程,可以在這裏安排一些上述的工作。
課程主題包含:
- 什麼是服務?
- 服務的生命週期
- 權限
- 進程生命週期
- 本地服務事例
- 遠程消息服務事例
什麼是服務?
大多數關於服務類的困擾實際上是圍繞着它不是什麼:
- 服務不是一個獨立的進程。服務對象本身並不意味着運行在它自己的進程中;除非另有說明,它運行在同一進程中作爲應用程序的一部分。
- 服務不是一個線程。但它並不意味着在主線程中工作(爲了避免應用程序無響應錯誤)。
因此,服務本身事實上非常簡單,它主要提供了兩個特點:
- 一個用於應用程序的工具,告訴系統它想在後臺做一些事情(即使用戶沒有直接與應用程序交互)。這對應於調用Context.startService(),告訴系統給服務安排工作,然後一直運行,直到服務本身或其他人明顯的停止它。
- 一個用於應用程序的工具,將自己的一些功能暴漏給其他應用使用。這對應於調用Context.bindService(),允許一個長期存在的服務連接,爲了可以和應用程序交互。
當一個服務組件真正創建後,針對上述原因,那麼系統實際上要做的就是實例化這個組件以及在主線程中調用onCreate()和其它適當的回調方法。這相當於服務實現了這些適當的行爲,比如,創建一個子線程並在其中進行自己的工作。
既然服務本身非常簡單,所以你可以按照你想要的和服務進行簡單或複雜的交互:從將其作爲一個本地java對象直接調用到提供了完整的遠程接口使用AIDL.
服務生命週期
一個服務可以由系統運行有兩個原因。如果某人調用Context.startService(),系統將會檢索這個服務(如果需要的話創建它並且調用onCreate()方法)以及調用帶有客戶端提供參數的onStartCommand(intent,int,int)方法。這個時候服務會一直運行直到Context.stopService或者stopSelf()方法被調用。注意多次調用Context.startService()不會嵌套(儘管在多個響應結果中會調用onStartCommand()),所以無論啓動了多少次服務都將會通過調用一次stopService()或者stopSelf()方法而終止服務。服務可以使用stopSelf(int)方法確保服務不會停止,直到開啓服務的意圖已經被處理。
對於開始服務,有兩種額外的主要的操作模式供我們選擇,這取決於我們在onStartCommand()方法中的返回值:START_STICKY用於根據需要明顯的開啓和關閉服務,而START_NOT_STICKY
和START_REDELIVER_INTENT
用於保持運行處理任何命令給服務(這點翻的不太通)。
客戶端也可以使用Context.bindService()來獲得一個持久連接的服務。者同樣會創建服務如果尚未運行(同時調用onCreate())但是不會調用onStartCommand(),客戶端將會獲得由onBind(intent)方法返回的Ibinder對象,允許客戶端回調服務。只要服務連接一旦建立,服務將會持續的運行(不管是否持有一個引用在服務的Ibinder中)。通常Ibinder返回的是一個用aidl寫的複雜接口。
一個服務可以同時開啓和連接綁定到它。在這種情況下,只要它是開啓的或者至少有一個連接使用Context.BIND_AUTO_CREATE標誌綁定到它,系統將一直使服務運行。一旦這兩種情形都沒有持有,服務的OnDestroy()方法將會被調用,服務將會有效的終止。所有的清理工作(停止線程、註銷服務)都應該在返回onDestroy()方法時完成。
下篇:
service服務<二>