Android ServiceConnection
綁定到一個(gè)Service
綁定是異步的.bindService()會(huì)立即返回,它不會(huì)返回IBinder給客戶端.要接收IBinder,客戶端必須創(chuàng)建一個(gè)ServiceConnection的實(shí)例并傳給bindService().ServiceConnection包含一個(gè)回調(diào)方法,系統(tǒng)調(diào)用這個(gè)方法來(lái)傳遞要返回的IBinder.
注:只有activities,services,和contentproviders可以綁定到一個(gè)service—你不能從一個(gè)broadcastreceiver綁定到service.
所以,從你的客戶端綁定到一個(gè)service,你必須:
-
1實(shí)現(xiàn)ServiceConnection.
你的實(shí)現(xiàn)必須重寫兩個(gè)回調(diào)方法:
-
onServiceConnected()
系統(tǒng)調(diào)用這個(gè)來(lái)傳送在service的onBind()中返回的IBinder.
-
OnServiceDisconnected()
Android系統(tǒng)在同service的連接意外丟失時(shí)調(diào)用這個(gè).比如當(dāng)service崩潰了或被強(qiáng)殺了.當(dāng)客戶端解除綁定時(shí),這個(gè)方法不會(huì)被調(diào)用.
-
-
2調(diào)用bindService(),傳給它ServiceConnection的實(shí)現(xiàn).
-
3當(dāng)系統(tǒng)調(diào)用你的onServiceConnected()方法時(shí),你就可以使用接口定義的方法們開始調(diào)用service了.
-
4要與service斷開連接,調(diào)用unbindService().
當(dāng)你的客戶端被銷毀,它將從service解除綁定,但是你必須總是在你完成與service的交互時(shí)或當(dāng)你的activity暫停于是service在不被使用時(shí)可以關(guān)閉此兩種情況下解除綁定.(下面會(huì)討論更多在適當(dāng)?shù)臅r(shí)候綁定和解除綁定的問(wèn)題.)
例如,下面是前一篇"派生Binder類"中創(chuàng)建的代碼片段,它把客戶端連接到了service.所有需要做的就是把返回的IBinder強(qiáng)制轉(zhuǎn)換到LocalBinder類并且請(qǐng)求LocalService實(shí)例:
[java]?view plaincopy使用這個(gè)ServiceConnection,客戶端可以綁定到一個(gè)service,通過(guò)把它傳給bindService().例如:
Intentintent = new Intent(this, LocalService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
-
第一個(gè)bindService()的參數(shù)是一個(gè)明確指定了要綁定的service的Intent.
-
第二個(gè)參數(shù)是ServiceConnection對(duì)象.
-
第三個(gè)參數(shù)是一個(gè)標(biāo)志,它表明綁定中的操作.它一般應(yīng)是BIND_AUTO_CREATE,這樣就會(huì)在service不存在時(shí)創(chuàng)建一個(gè).其它可選的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定時(shí)設(shè)為0即可.
補(bǔ)充事項(xiàng)
下面是一些關(guān)于綁定到service的重要事項(xiàng):
-
你總是需要捕獲DeadObjectException異常.它會(huì)在連接被打斷時(shí)拋出.這是被遠(yuǎn)程方法拋出的唯一異常.
-
對(duì)象引用計(jì)數(shù)是跨進(jìn)程的作用的.
-
你應(yīng)該在客戶端的生命期內(nèi)使綁定和解除綁定配對(duì)進(jìn)行,例如:
-
如果你需要在你的activity可見時(shí)與service交互,你應(yīng)該在onStart()綁定并在onStop()中解除綁定.
-
如果你想讓你的activity即使在它停止時(shí)也能接收回應(yīng),那么你可以在onCreate()中綁定并在onDestroy()中解除綁定.注意這意味著你的activity需要使用在自己整個(gè)運(yùn)行期間使用service(即使位于后臺(tái)),所以如果service在另一個(gè)進(jìn)程中,那么你增加了這個(gè)進(jìn)程的負(fù)擔(dān)而使它變得更容易被系統(tǒng)殺掉.
-
注:你一般不應(yīng)該在你的activity的onResume()和onPause()中綁定和解除綁定到service,因?yàn)檫@些回調(diào)方法,出現(xiàn)在每個(gè)生命期變化中,并且你需要使發(fā)生在這些變化中的處理最小化.還有,如果你應(yīng)用中的多個(gè)activity綁定到同一個(gè)service,并且有一個(gè)變化發(fā)生在其中兩個(gè)activity之間,service可能在當(dāng)前activity解除綁定(pause中)和下一個(gè)綁定前(rusume中)被銷毀又重建.
管理BoundService的生命期
當(dāng)一個(gè)service的所有客戶端都解除綁定,Android系統(tǒng)就銷毀它(除非它是從onStartCommand()啟動(dòng)).如果你的service是一個(gè)純boundservice,你不需管理它的生命期—Android系統(tǒng)會(huì)為你管理它.
然而,如果你選擇了實(shí)現(xiàn)onStartCommand()回調(diào)方法,那么你必須明確地停止service,因?yàn)?/span>service現(xiàn)在被認(rèn)為是"開始的".在此情況下,service會(huì)一直運(yùn)行,直到service使用stopSelf()停止它自己或另外的組件調(diào)用了stopService()停止了它,不管是否有客戶端綁定了它.
另外,如果你的service已經(jīng)啟動(dòng)并且接受綁定,那么當(dāng)系統(tǒng)調(diào)用你的onUnbind()方法,你可以選擇返回true表示你想在客戶端下一次綁定到service時(shí)接受一個(gè)對(duì)onRebind()的調(diào)用(而不是一個(gè)對(duì)onBind()的調(diào)用).onRebind()返回void,但是客戶端依然會(huì)在它的onServiceConnected()回調(diào)中接收到IBinder.下圖演示了這種生命其的邏輯:
圖1.一個(gè)已開始并已綁定的service的生命期
總結(jié)
以上是生活随笔為你收集整理的Android ServiceConnection的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 模块基础
- 下一篇: Android中的Broadcast A