綁定式服務的介紹
學習筆記,歡迎指導。
△綁定式的服務定義:一個由bindService()方法所開啓的服務成爲綁定式的服務。
→其他組件可以與該服務綁定,同時可以與他進行通信(包括向服務發送請求,接收服務所返回的和數據,你還可以通過這個服務進行進程間的通信)。
→一個綁定式的服務不可以在後臺無限期地執行,當所有與他相綁定的組件都與他解綁,這個服務就會銷燬(當不再有組件與他綁定,系統會自動將幹掉他)。
△綁定式服務的基礎知識
→他是Service的子類,開發者要覆寫onBind()方法,這個方法返回一個IBinder對象,這個對象裏面定義一個公有方法,與服務綁定的組件通過該方法與服務進行通信。
→客戶端(客戶端就是想要與服務相綁定的那個組件)通過方法:bindService與服務綁定。
→一個服務可以在同一個時間與多個客戶端綁定,系統會向每一個與服務綁定的客戶端傳第一個:IBinder對象,但是,只有第一個與服務想綁定的客戶端的”IBinder”對象是通過onBind方法返回的,其他與服務綁定的客戶端的”IBinder”對象不是通過onBind方法返回。即onbind()方法只會調用一次。
→當最後一個與服務相綁定的客戶端也解綁定了,系統將會銷燬服務。
△創建一個綁定式的服務
→當你的服務工作於不同場合(工作於一個應用的內部;工作於不同的進程之間),使用不同創建方法。本文只是講述作用於單一應用內部的服務。
→當服務只是工作在自己應用內部,方法如下:在你的服務類內部,定義一個內部類去繼承Binder(),然後,在onBind方法裏,返回一個該內部類實例。
△具體步驟:
→首先,綁定服務的本質是,在窗體那獲取服務實例,然後就能直接調用服務裏的公有方法(這有點類似於Fragment與窗體通信的做法)。
→在服務裏完成步驟:
(1)定義一個內部類繼承Binder類,該內部類裏面定義一個共有方法,該方法將當前服務實例返回。
(2)在服務的onBind方法裏面,將該內部類的實例返回。看代碼
public class MService extends Service {
//創建一個內部類的實例
private MyBinder myBinder = new MyBinder();
public void onCreate() {
super.onCreate();
Log.i("test", "--onCreate--");
}
//第一步:定義一個類去繼承Binder
public class MyBinder extends Binder{
//內部類裏定義一個公有方法
public MService getService(){
return MService.this;//將當前服務的實例返回
}
}
//第二步:在服務的onBind方法裏面
//將該內部類的實例返回
@Override
public IBinder onBind(Intent intent) {
Log.i("test", "--onBind--");
return myBinder;
}
}
→在客戶端(我這裏將窗體做客戶端)完成步驟:
(1)定義一個內部類,該內部類實現接口”ServiceConnection”,同時實現接口裏的兩個方法:”onServiceConnection”(客戶端在這個方法方法體裏得到Binder對象,由該對象就能得到服務實例)、”onServiceDisConnection”(當服務被意外斷開,系統將會回調這個方法)。
(2)分別創建服務類變量、內部類變量(內部類變量需要實例化),在”onServiceConnection”方法裏面用得到的服務實例將服務類變量實例化
(3)在需要綁定服務的地方,調用bindService()方法,將內部類變量傳入。
看代碼:代碼註釋已經寫好代碼編寫時的順序,這個順序只是便於理解而已。
public class MainActivity extends Activity implements View.OnClickListener {
//第二步:創建內部類變量以及服務類的變量
//同時實例化內部類變量
private MService mService = null;
private MServiceConnection mServiceConnection =
new MServiceConnection();
//窗體的初始化方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.bt_bind_the_service)
.setOnClickListener(this);
}
//點擊事件響應函數
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt_bind_the_service:
Intent intent =
new Intent(MainActivity.this, MService.class);
//第三步:綁定服務那個時候將接口的實例傳入
bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE);
break;
}
}
//第一步:定義一個內部類去實現接口”ServiceConnection”
class MServiceConnection implements ServiceConnection{
//這個方法裏面那個service
//就是服務類裏面的onBind()方法所返回的IBinder變量了
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//還是第二步:將服務類的變量實例化:
//將IBinder向下轉型
MService.MyBinder myBinder = (MService.MyBinder)service;
//調用公有方法就能獲得服務類的實例
mService = myBinder.getService();
Log.i("test","連接服務");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("test", "意外斷開");
}
}
}
→總結一下做了什麼:
在服務裏,繼承Binder同時定義公有方法,通過onBind()方法將服務類實例傳遞給客戶端。
在客戶端,通過bindService()綁定服務,同時通過”ServiceConnection”接口裏的”onServiceConnection”方法獲取服務實例。
注意:你最好定義一個布爾型變量,每次綁定服務或者解綁定時都要修改這個標記。