Service元件(startService,stopService,bindService,unbindService方法比較)-Android
Service是執行在主執行緒中的.如果需要執行非同步操作,可以考慮IntentServcie。Service比Activity具有更高的優先順序,只有在系統資源極度匱乏的情況下,android系統才可能清理掉一部分service來保證系統的執行,而這種情況卻又輕易不會出現。即使Service被系統終止了,在系統資源恢復後Service也將自動恢復執行狀態,因此可以認為Service是在系統中永久執行的元件。Service除了實現後臺服務功能,還可以用於程序間通訊,解決兩個不同Activity應用程式程序之間的呼叫和通訊問題。
1.service分類:
一般我們認為service分為兩類,本地service和遠端service。本地service顧名思義,那就是和當前應用在同一個程序中的service,彼此之間擁有共同的記憶體區域,所以對於某些資料的共享特別的方便和簡單;
遠端service:主要牽扯到不同程序間的service訪問。因為android的系統安全的原因導致了我們在不同的程序間無法使用一般的方式共享資料。在這裡android為我們提供了一個AIDL
2.service生命週期:
和Activity相比,service的生命週期已經簡單的不能再簡單了,只有onCreate()->onStart()->onDestroy()三個方法。
> Activity中和service有關的方法:startService(Intent intent):啟動一個service
stopService(Intent intent) :停止一個service
> 如果我們想使用service中的一些資料或者訪問其中的一些方法,那麼我們就要通過下面的方法:
public boolean bindService
public void unbindService(ServiceConnection conn);
intent是跳轉到service的intent,如 Intent intent = new Intent(); intent.setClass(this,MyService.class);
conn則是一個代表與service連線狀態的類,當我們連線service成功或失敗時,會主動觸發其內部的onServiceConnected或onServiceDisconnected方法。如果我們想要訪問service中的資料,可以在onServiceConnected()方法中進行實現,
> Service的bindService()的生命週期:
context.bindService() ——> onCreate() ——> onBind() ——> Service running ——> onUnbind() ——> onDestroy() ——> Service stop
onBind()將返回給客戶端一個IBind介面例項,IBind允許客戶端回撥服務的方法,比如得到Service的例項、執行狀態或其他操作。這個時候把呼叫者(Context,例如Activity)會和Service繫結在一起,Context退出了,Srevice就會呼叫onUnbind->onDestroy相應退出。所以呼叫bindService的生命週期為:onCreate --> onBind(只一次,不可多次繫結) --> onUnbind --> onDestory。在Service每一次的開啟關閉過程中,只有onStart可被多次呼叫(通過多次startService呼叫),其他onCreate,onBind,onUnbind,onDestory在一個生命週期中只能被呼叫一次。
3.service服務執行的邏輯流程
> startService() 服務
service通過Context.startService()方法開始,通過Context.stopService()方法停止;也可以通過Service.stopSelf()方法或者Service.stopSelfResult()方法來停止自己。只要呼叫一次stopService()方法便可以停止服務,無論之前它被呼叫了多少次的啟動服務方法。
> bindService()服務
客戶端建立一個與Service的連線,並使用此連線與Service進行通話,通過Context.bindService()方法來繫結服務,Context.unbindService()方法來關閉服務。多個客戶端可以繫結同一個服務,如果Service還未被啟動,bindService()方法可以啟動服務。上面startService()和bindService()兩種模式是完全獨立的。你可以繫結一個已經通過startService()方法啟動的服務。例如:一個後臺播放音樂服務可以通過startService(intend)物件來播放音樂。可能使用者在播放過程中要執行一些操作比如獲取歌曲的一些資訊,此時activity可以通過呼叫bindServices()方法與Service建立連線。這種情況下,stopServices()方法實際上不會停止服務,直到最後一次繫結關閉。
如果沒有程式停止它或者它自己停止,service將一直執行。在這種模式下,service開始於呼叫Context.startService() ,停止於Context.stopService(). service可以通過呼叫Android Service 生命週期() 或 Service.stopSelfResult()停止自己。不管呼叫多少次startService() ,只需要呼叫一次 stopService() 就可以停止service。
可以通過介面被外部程式呼叫。外部程式建立到service的連線,通過連線來操作service。建立連線調開始於Context.bindService(), 結束於Context.unbindService(). 多個客戶端可以繫結到同一個service,如果service沒有啟動, bindService() 可以選擇啟動它。
這兩種模式不是完全分離的。你可以可以繫結到一個通過startService()啟動的服務。如一個intent想要播放音樂,通過startService() 方法啟動後臺播放音樂的service。然後,也許使用者想要操作播放器或者獲取當前正在播放的樂曲的資訊,一個activity就會通過bindService()建立一個到此service的連線. 這種情況下 stopService() 在全部的連線關閉後才會真正停止service。
> 如果一個service允許別人繫結,那麼需要實現以下額外的方法:IBinder onBind(Intent intent); boolean onUnbind(Intent intent); void onRebind(Intent intent)
onBind()回撥方法會繼續傳遞通過bindService()傳遞來的intent物件;onUnbind()會處理傳遞給unbindService()的intent物件。如果service允許繫結,onBind()會返回客戶端與服務互相聯絡的通訊控制代碼(例項)。如果建立了一個新的客戶端與服務的連線,onUnbind()方法可以請求呼叫onRebind()方法。
記住: 任何服務無論它怎樣建立,預設客戶端都可以連線,所以任何service都能夠接收onBind()和onUnbind()方法。
> 服務不能自己執行,需要通過呼叫Context.startService()或Context.bindService()方法啟動服務。這兩個方法都 可以啟動Service,但是它們的使用場合有所不同。使用startService()方法啟用服務,呼叫者與服務之間沒有關連,即使呼叫者退出了,服 務仍然執行。使用bindService()方法啟用服務,呼叫者與服務繫結在了一起,呼叫者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的 特點。
如果打算採用Context.startService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的onCreate()方法,接著呼叫onStart()方法。如果呼叫startService()方法前服務已經被建立,多次呼叫startService()方法並不會導致多次建立服務,但會導致多次呼叫onStart()方法。採用startService()方法啟動的服務,只能呼叫Context.stopService()方法結束服務,服務結束時會呼叫onDestroy()方法。
如果打算採用Context.bindService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的 onCreate()方法,接著呼叫onBind()方法。這個時候呼叫者和服務繫結在一起,呼叫者退出了,系統就會先呼叫服務的onUnbind()方 法,接著呼叫onDestroy()方法。如果呼叫bindService()方法前服務已經被繫結,多次呼叫bindService()方法並不會導致 多次建立服務及繫結(也就是說onCreate()和onBind()方法並不會被多次呼叫)。如果呼叫者希望與正在繫結的服務解除繫結,可以呼叫 unbindService()方法,呼叫該方法也會導致系統呼叫服務的onUnbind()-->onDestroy()方法。