請記住秒裕,如果你使用了服務瞒渠,它默認就運行于應用程序的主線程中。因此态鳖,如果服務執(zhí)行密集計算或者阻塞操作,你仍然應該在服務中創(chuàng)建一個新的線程來完成
onStartCommand()
當其它組件恶导,比如一個activity浆竭,通過調用startService()請求started方式的服務時,系統(tǒng)將會調用本方法惨寿。 一旦本方法執(zhí)行邦泄,服務就被啟動,并在后臺一直運行下去裂垦。 如果你的代碼實現(xiàn)了本方法顺囊,你就有責任在完成工作后通過調用stopSelf()或stopService()終止服務。 (如果你只想提供bind方式蕉拢,那就不需要實現(xiàn)本方法特碳。)
如果組件通過調用startService()(這會導致onStartCommand()的調用)啟動了服務,那么服務將一直保持運行晕换,直至自行用stopSelf()終止或由其它組件調用stopService()來終止它午乓。
如果組件調用bindService()來創(chuàng)建服務(那onStartCommand()就不會被調用),則服務的生存期就與被綁定的組件一致闸准。一旦所有客戶端都對服務解除了綁定益愈,系統(tǒng)就會銷毀該服務。
與activity一樣,服務可以定義intent過濾器蒸其,使得其它組件能用隱式intent來調用服務敏释。 通過聲明intent過濾器,任何安裝在用戶設備上的應用程序組件都有能力來啟動你的服務摸袁,只要你的服務所聲明的intent過濾器與其它應用程序傳遞給startService()的intent相匹配即可钥顽。
此外,如果包含了android:exported屬性并且設置為"false"靠汁, 就可以確保該服務是你應用程序的私有服務耳鸯。即使服務提供了intent過濾器,本屬性依然生效膀曾。?
IntentService
這是Service類的子類县爬,它使用了工作(worker)線程來處理所有的啟動請求,每次請求都會啟動一個線程添谊。 如果服務不需要同時處理多個請求的話财喳,這是最佳的選擇。 所有你要做的工作就是實現(xiàn)onHandleIntent()即可斩狱,它會接收每個啟動請求的intent耳高,然后就可在后臺完成工作
IntentService將執(zhí)行以下步驟:
創(chuàng)建一個缺省的工作(worker)線程,它獨立于應用程序主線程來執(zhí)行所有發(fā)送到onStartCommand()的intent所踊。
好處:
創(chuàng)建一個工作隊列泌枪,每次向你的onHandleIntent()傳入一個intent,這樣你就永遠不必擔心多線程問題了秕岛。
在處理完所有的啟動請求后碌燕,終止服務,因此你就永遠不需調用stopSelf()了继薛。
提供缺省的onBind()實現(xiàn)代碼修壕,它返回null。
提供缺省的onStartCommand()實現(xiàn)代碼遏考,它把intent送入工作隊列慈鸠,稍后會再傳給你的onHandleIntent()實現(xiàn)代碼。?
START_NOT_STICKY
如果系統(tǒng)在onStartCommand()返回后殺死了服務灌具,則不會重建服務了青团,除非還存在未發(fā)送的intent。 當服務不再是必需的咖楣,并且應用程序能夠簡單地重啟那些未完成的工作時督笆,這是避免服務運行的最安全的選項。
START_STICKY
如果系統(tǒng)在onStartCommand()返回后殺死了服務截歉,則將重建服務并調用onStartCommand()胖腾,但不會再次送入上一個intent烟零, 而是用null intent來調用onStartCommand() 瘪松。除非還有啟動服務的intent未發(fā)送完咸作,那么這些剩下的intent會繼續(xù)發(fā)送。 這適用于媒體播放器(或類似服務)宵睦,它們不執(zhí)行命令记罚,但需要一直運行并隨時待命。
START_REDELIVER_INTENT
如果系統(tǒng)在onStartCommand()返回后殺死了服務壳嚎,則將重建服務并用上一個已送過的intent調用onStartCommand()桐智。任何未發(fā)送完的intent也都會依次送入。這適用于那些需要立即恢復工作的活躍服務烟馅,比如下載文件说庭。
創(chuàng)建一個bound服務
要創(chuàng)建一個bound服務,你必須實現(xiàn)onBind()回調方法郑趁,并返回一個IBinder對象刊驴,此對象定義了與服務進行通信的接口。 然后寡润,其它應用程序組件可以調用bindService()來獲得接口并調用服務中的方法捆憎。 服務只在為綁定的應用程序組件工作時才會存活,因此梭纹,只要沒有組件綁定到服務躲惰,系統(tǒng)就會自動銷毀服務(你不需要像started服務中那樣通過onStartCommand()來終止一個bound服務)。
同一個服務可以被多個客戶端綁定变抽。當客戶端完成交互時础拨,會調用unbindService()來解除綁定。一旦不存在客戶端與服務綁定時绍载,系統(tǒng)就會銷毀該服務太伊。
一旦開始運行,服務就能夠利用toast通知或狀態(tài)欄通知把事件通知給用戶逛钻。?
在前臺運行服務
要把你的服務請求為前臺運行僚焦,可以調用startForeground()方法。此方法有兩個參數:唯一標識通知的整數值曙痘、狀態(tài)欄通知Notification對象芳悲。例如:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION, notification);
要從前臺移除服務,請調用stopForeground()方法边坤,這個方法接受個布爾參數名扛,表示是否同時移除狀態(tài)欄通知。此方法不會終止服務茧痒。不過肮韧,如果服務在前臺運行時被你終止了,那么通知也會同時被移除。
不管是用startService()創(chuàng)建的弄企,還是用bindService()創(chuàng)建的超燃,所有的服務都會調用onCreate()和onDestroy()方法。?
from->http://www.android-doc.com/guide/components/services.html