1. 程式人生 > >Android裡Service的bindService()和startService()混合使用深入分析

Android裡Service的bindService()和startService()混合使用深入分析

先講講怎麼使用bindService()繫結服務

應用元件(客戶端)可以呼叫bindService()繫結到一個service.Android系統之後呼叫service的onBind()方法,它返回一個用來與service互動的IBinder繫結是非同步的.bindService()會立即返回,它不會返回IBinder給客戶端.要接收IBinder,客戶端必須建立一個ServiceConnection的例項並傳給bindService().ServiceConnection包含一個回撥方法,系統呼叫這個方法來傳遞要返回的IBinder.

注:只有activities,services,和contentproviders可以繫結到一個service—你不能從一個broadcastreceiver繫結到service.

broadcastreceiver的context生命週期很短暫,bindservice沒有什麼意義。

bindService步驟

1實現ServiceConnection.
你的實現必須重寫兩個回撥方法:
onServiceConnected()
系統呼叫這個來傳送在service的onBind()中返回的IBinder.
OnServiceDisconnected()
Android系統在同service的連線意外丟失時呼叫這個.比如當service崩潰了或被強殺了.當客戶端解除繫結時,這個方法不會被呼叫.
2呼叫bindService(),傳給它ServiceConnection的實現.
3當系統呼叫你的onServiceConnected()方法時,你就可以使用介面定義的方法們開始呼叫service了.
4要與service斷開連線,呼叫unbindService().
當你的客戶端被銷燬,它將從service解除繫結,但是你必須總是在你完成與service的互動時或當你的activity暫停於是service在不被使用時可以關閉此兩種情況下解除繫結.(下面會討論更多在適當的時候繫結和解除繫結的問題.
使用這個ServiceConnection,客戶端可以繫結到一個service,通過把它傳給bindService().例如:
Intentintent = new Intent(this, LocalService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
第一個bindService()的引數是一個明確指定了要繫結的service的Intent.
第二個引數是ServiceConnection物件.
第三個引數是一個標誌,它表明繫結中的操作.它一般應是BIND_AUTO_CREATE,這樣就會在service不存在時建立一個.其它可選的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定時設為0即可.。

補充事項

下面是一些關於繫結到service的重要事項:

你總是需要捕獲DeadObjectException異常.它會在連線被打斷時丟擲.這是被遠端方法丟擲的唯一異常.
物件引用計數是跨程序的作用的.
你應該在客戶端的生命期內使繫結和解除繫結配對進行,例如:
如果你需要在你的activity可見時與service互動,你應該在onStart()繫結並在onStop()中解除繫結.
如果你想讓你的activity即使在它停止時也能接收回應,那麼你可以在onCreate()中繫結並在onDestroy()中解除繫結.注意這意味著你的activity需要使用在自己整個執行期間使用service(即使位於後臺),所以如果service在另一個程序中,那麼你增加了這個程序的負擔而使它變得更容易被系統殺掉.
注:你一般不應該在你的activity的onResume()和onPause()中繫結和解除繫結到service,因為這些回撥方法,出現在每個生命期變化中,並且你需要使發生在這些變化中的處理最小化.還有,如果你應用中的多個activity繫結到同一個service,並且有一個變化發生在其中兩個activity之間,service可能在當前activity解除繫結(pause中)和下一個繫結前(rusume中)被銷燬又重建.

管理(多個客戶端)BoundService的生命期

當一個service的所有客戶端都解除繫結,Android系統就銷燬它(除非它是從onStartCommand()啟動).如果你的service是一個純boundservice,你不需管理它的生命週期—Android系統會為你管理它.。

然而,如果你選擇了實現onStartCommand()回撥方法,那麼你必須明確地停止service,因為service現在被認為是"開始的".在此情況下,service會一直執行,直到service使用stopSelf()停止它自己或另外的元件呼叫了stopService()停止了它,不管是否有客戶端綁定了它.另外,如果你的service已經啟動並且接受繫結,那麼當系統呼叫你的onUnbind()方法,你可以選擇返回true表示你想在客戶端下一次繫結到service時接受一個對onRebind()的呼叫(而不是一個對onBind()的呼叫).onRebind()返回void,但是客戶端依然會在它的onServiceConnected()回撥中接收到IBinder.下圖演示了這種生命其的邏輯:


bindService和startService混合使用時

1.如果先bindService,再startService:
在bind的Activity退出的時候,Service會執行unBind方法而不執行onDestory方法,因為有startService方法呼叫過,所以Activity與Service解除繫結後會有一個與呼叫者沒有關連的Service存在
2.如果先bindService,再startService,再呼叫Context.stopService

Service的onDestory方法不會立刻執行,因為有一個與Service繫結的Activity,但是在Activity退出的時候,會執行onDestory,如果要立刻執行stopService,就得先解除繫結。

把上面的"如果先bindService,再startService"換成"如果先startService,再bindService",結果是一樣的

當一個服務沒被onDestory()銷燬之前,只有第一個啟動它的客戶端能呼叫它的onBind()和onUnbind()。

歡迎掃描二維碼,關注公眾賬號