1,在編寫Android應(yīng)用程序時岁忘,我們一般將一些計算型的邏輯放在一個獨立的進(jìn)程來處理辛慰,這樣主進(jìn)程仍然可以流暢地響應(yīng)界面事件,提高用戶體驗干像。Android系統(tǒng)為我們提供了一個Service類帅腌,我們可以實現(xiàn)一個以Service為基類的服務(wù)子類,在里面實現(xiàn)自己的計算型邏輯麻汰,然后在主進(jìn)程通過startService函數(shù)來啟動這個服務(wù)狞膘。
在主進(jìn)程調(diào)用startService函數(shù)時,會通過Binder進(jìn)程間通信機(jī)制來通知ActivitManagerService來創(chuàng)建新進(jìn)程什乙,并且啟動指定的服務(wù)。
startService(new Intent("shy.luo.ashmem.server"));
這里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字已球,用來告訴Android系統(tǒng)它所要啟動的服務(wù)的名字:
<service?
? ? ? ? ? ? ? ? android:enabled="true"?
? ? ? ? ? ? ? ? android:name=".Server"?
? ? ? ? ? ? ? ? android:process=".Server" >?
? ? ? ? ? ? ? ? ? ? <intent-filter>?
? ? ? ? ? ? ? ? ? ? ? ? <action android:name="shy.luo.ashmem.server"/>?
? ? ? ? ? ? ? ? ? ? ? ? <category android:name="android.intent.category.DEFAULT"/>?
? ? ? ? ? ? ? ? ? ? </intent-filter>?
? ? ? ? ? ? </service>
這里臣镣,名字“shy.luo.ashmem.server”對應(yīng)的服務(wù)類為shy.luo.ashmem.Server,下面語句:
startService(new Intent("shy.luo.ashmem.server"));?
就表示要在一個新的進(jìn)程中啟動shy.luo.ashmem.Server這個服務(wù)類智亮,它必須繼承于Android平臺提供的Service類
2忆某,這樣,Android系統(tǒng)在新進(jìn)程中啟動服務(wù)的過程就分析完成了阔蛉,雖然很復(fù)雜弃舒,但是條理很清晰。它通過三次Binder進(jìn)程間通信完成了服務(wù)的啟動過程,分別是:
1). Step 1至Step 7聋呢,從主進(jìn)程調(diào)用到ActivityManagerService進(jìn)程中苗踪,完成新進(jìn)程的創(chuàng)建;
2). Step 8至Step 11削锰,從新進(jìn)程調(diào)用到ActivityManagerService進(jìn)程中通铲,獲取要在新進(jìn)程啟動的服務(wù)的相關(guān)信息;
3). Step 12至Step 20器贩,從ActivityManagerService進(jìn)程又回到新進(jìn)程中颅夺,最終將服務(wù)啟動起來。
學(xué)習(xí)完Android系統(tǒng)在新進(jìn)程中啟動服務(wù)的過程后蛹稍,希望讀者對Android系統(tǒng)的Service有一個深刻的理解吧黄。在編寫Android應(yīng)用程序的時候,盡量把一些計算型的邏輯以Service在形式來實現(xiàn)唆姐,使得這些耗時的計算能在一個獨立的進(jìn)程中進(jìn)行拗慨,這樣就能保持主進(jìn)程流暢地響應(yīng)界面事件,提高用戶體驗厦酬。
3胆描,如果你的 Thread 需要不停地隔一段時間就要連接服務(wù)器做某種同步的話,該 Thread 需要在 Activity 沒有start的時候也在運行仗阅。這個時候當(dāng)你 start 一個 Activity 就沒有辦法在該 Activity 里面控制之前創(chuàng)建的 Thread昌讲。因此你便需要創(chuàng)建并啟動一個 Service ,在 Service 里面創(chuàng)建减噪、運行并控制該 Thread短绸,這樣便解決了該問題(因為任何 Activity 都可以控制同一 Service,而系統(tǒng)也只會創(chuàng)建一個對應(yīng) Service 的實例)筹裕。
因此你可以把 Service 想象成一種消息服務(wù)醋闭,而你可以在任何有 Context 的地方調(diào)用 Context.startService、Context.stopService朝卒、Context.bindService证逻,Context.unbindService,來控制它抗斤,你也可以在 Service 里注冊 BroadcastReceiver囚企,在其他地方通過發(fā)送 broadcast 來控制它,當(dāng)然這些都是 Thread 做不到的瑞眼。
4龙宏,Service的生命周期
onCreate onStart onDestroy onBind
1). 被啟動的服務(wù)的生命周期:如果一個Service被某個Activity 調(diào)用 Context.startService 方法啟動,那么不管是否有Activity使用bindService綁定或unbindService解除綁定到該Service伤疙,該Service都在后臺運行银酗。如果一個Service被startService 方法多次啟動,那么onCreate方法只會調(diào)用一次,onStart將會被調(diào)用多次(對應(yīng)調(diào)用startService的次數(shù))黍特,并且系統(tǒng)只會創(chuàng)建Service的一個實例(因此你應(yīng)該知道只需要一次stopService調(diào)用)蛙讥。該Service將會一直在后臺運行,而不管對應(yīng)程序的Activity是否在運行衅澈,直到被調(diào)用stopService键菱,或自身的stopSelf方法。當(dāng)然如果系統(tǒng)資源不足今布,android系統(tǒng)也可能結(jié)束服務(wù)经备。
2). 被綁定的服務(wù)的生命周期:如果一個Service被某個Activity 調(diào)用 Context.bindService 方法綁定啟動,不管調(diào)用 bindService 調(diào)用幾次部默,onCreate方法都只會調(diào)用一次侵蒙,同時onStart方法始終不會被調(diào)用。當(dāng)連接建立之后傅蹂,Service將會一直運行纷闺,除非調(diào)用Context.unbindService 斷開連接或者之前調(diào)用bindService 的 Context 不存在了(如Activity被finish的時候),系統(tǒng)將會自動停止Service份蝴,對應(yīng)onDestroy將被調(diào)用犁功。
3). 被啟動又被綁定的服務(wù)的生命周期:如果一個Service又被啟動又被綁定,則該Service將會一直在后臺運行婚夫。并且不管如何調(diào)用浸卦,onCreate始終只會調(diào)用一次,對應(yīng)startService調(diào)用多少次案糙,Service的onStart便會調(diào)用多少次限嫌。調(diào)用unbindService將不會停止Service,而必須調(diào)用 stopService 或 Service的 stopSelf 來停止服務(wù)时捌。
4). 當(dāng)服務(wù)被停止時清除服務(wù):當(dāng)一個Service被終止(1怒医、調(diào)用stopService;2奢讨、調(diào)用stopSelf稚叹;3、不再有綁定的連接(沒有被啟動))時拿诸,onDestroy方法將會被調(diào)用入录,在這里你應(yīng)當(dāng)做一些清除工作,如停止在Service中創(chuàng)建并運行的線程佳镜。
5,特別注意:
1)凡桥、你應(yīng)當(dāng)知道在調(diào)用 bindService 綁定到Service的時候蟀伸,你就應(yīng)當(dāng)保證在某處調(diào)用 unbindService 解除綁定(盡管 Activity 被 finish 的時候綁定會自 動解除,并且Service會自動停止);
2)啊掏、你應(yīng)當(dāng)注意 使用 startService 啟動服務(wù)之后蠢络,一定要使用 stopService停止服務(wù),不管你是否使用bindService迟蜜;
3)刹孔、同時使用 startService 與 bindService 要注意到,Service 的終止娜睛,需要unbindService與stopService同時調(diào)用髓霞,才能終止 Service,不管 startService 與 bindService 的調(diào)用順序畦戒,如果先調(diào)用 unbindService 此時服務(wù)不會自動終止方库,再調(diào)用 stopService 之后服務(wù)才會停止,如果先調(diào)用 stopService 此時服務(wù)也不會終止障斋,而再調(diào)用 unbindService 或者 之前調(diào)用 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之后服務(wù)才會自動停止纵潦;
4)、當(dāng)在旋轉(zhuǎn)手機(jī)屏幕的時候垃环,當(dāng)手機(jī)屏幕在“橫”“豎”變換時邀层,此時如果你的 Activity 如果會自動旋轉(zhuǎn)的話,旋轉(zhuǎn)其實是 Activity 的重新創(chuàng)建遂庄,因此旋轉(zhuǎn)之前的使用 bindService 建立的連接便會斷開(Context 不存在了)寥院,對應(yīng)服務(wù)的生命周期與上述相同。
5)涧团、在 sdk 2.0 及其以后的版本中只磷,對應(yīng)的 onStart 已經(jīng)被否決變?yōu)榱?onStartCommand,不過之前的 onStart 任然有效泌绣。這意味著钮追,如果你開發(fā)的應(yīng)用程序用的 sdk 為 2.0 及其以后的版本,那么你應(yīng)當(dāng)使用 onStartCommand 而不是 onStart阿迈。