http://www.cnblogs.com/ruiati/archive/2013/10/20/3379380.html
繼承Binder類
這個方式只有當你的Acitivity和Service處于同一個Application和進程時,才可以用,比如你后臺有一個播放背景音樂的Service,這時就可以用這種方式來進行通信。
用例子來說明其使用方法:
1. 來看Service的寫法:
publicclassLocalServiceextendsService?{
//?實例化自定義的Binder類
privatefinalIBinder?mBinder?=newLocalBinder();
//?隨機數的生成器
privatefinalRandom?mGenerator?=newRandom();
/**
*?自定義的Binder類,這個是一個內部類,所以可以知道其外圍類的對象,通過這個類,讓Activity知道其Service的對象
*/
publicclassLocalBinderextendsBinder?{
LocalService?getService()?{
//?返回Activity所關聯的Service對象,這樣在Activity里,就可調用Service里的一些公用方法和公用屬性
returnLocalService.this;
}
}
@Override
publicIBinder?onBind(Intent?intent)?{
returnmBinder;
}
/**?public方法,Activity可以進行調用?*/
publicintgetRandomNumber()?{
returnmGenerator.nextInt(100);
}
}
在Service里定義一個內部類,Binder的子類,通過這個類,把Service的對象傳給Activity,這樣Activity就可以調用Service里的公用方法和公用屬性了,但這種方式,一定要在同一個進程和同一個Application里。
2. 再看相應Activity的代碼:
publicclassBindingActivityextendsActivity?{
LocalService?mService;
booleanmBound?=false;
@Override
protectedvoidonCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protectedvoidonStart()?{
super.onStart();
//?綁定Service,綁定后就會調用mConnetion里的onServiceConnected方法
Intent?intent?=newIntent(this,?LocalService.class);
bindService(intent,?mConnection,?Context.BIND_AUTO_CREATE);
}
@Override
protectedvoidonStop()?{
super.onStop();
//?解綁Service,這樣可以節(jié)約內存
if(mBound)?{
unbindService(mConnection);
mBound?=false;
}
}
/**?用戶點擊button,就讀取Service里的隨機數?*/
publicvoidonButtonClick(View?v)?{
if(mBound)?{
//?用Service的對象,去讀取隨機數
intnum?=?mService.getRandomNumber();
Toast.makeText(this,"number:?"+?num,?Toast.LENGTH_SHORT).show();
}
}
/**?定交ServiceConnection,用于綁定Service的*/
privateServiceConnection?mConnection?=newServiceConnection()?{
@Override
publicvoidonServiceConnected(ComponentName?className,
IBinder?service)?{
//?已經綁定了LocalService,強轉IBinder對象,調用方法得到LocalService對象
LocalBinder?binder?=?(LocalBinder)?service;
mService?=?binder.getService();
mBound?=true;
}
@Override
publicvoidonServiceDisconnected(ComponentName?arg0)?{
mBound?=false;
}
};
}
這里就是通過IBinder來得到LocalService對象,再去調用其Public方法。
使用Messenger
上面的方法只能在同一個進程里才能用,如果要與另外一個進程的Service進行通信,則可以用Messenger。
其實實現IPC的方式,還有AIDL,但推薦使用Messenger,有兩點好處:
1. 使用Messenger方式比使用AIDL的方式,實現起來要簡單很多
2. 使用Messenger時,所有從Activity傳過來的消息都會排在一個隊列里,不會同時請求Service,所以是線程安全的。如果你的程序就是要多線程去訪問Service,就可以用AIDL,不然最好使用Messenger的方式。
不過,其實Messenger底層用的就是AIDL實現的,看一下實現方式,先看Service的代碼:
publicclassMessengerServiceextendsService?{
/**?用于Handler里的消息類型?*/
staticfinalintMSG_SAY_HELLO?=1;
/**
*?在Service處理Activity傳過來消息的Handler
*/
classIncomingHandlerextendsHandler?{
@Override
publicvoidhandleMessage(Message?msg)?{
switch(msg.what)?{
caseMSG_SAY_HELLO:
Toast.makeText(getApplicationContext(),"hello!",?Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
*?這個Messenger可以關聯到Service里的Handler,Activity用這個對象發(fā)送Message給Service,Service通過Handler進行處理。
*/
finalMessenger?mMessenger?=newMessenger(newIncomingHandler());
/**
*?當Activity綁定Service的時候,通過這個方法返回一個IBinder,Activity用這個IBinder創(chuàng)建出的Messenger,就可以與Service的Handler進行通信了
*/
@Override
publicIBinder?onBind(Intent?intent)?{
Toast.makeText(getApplicationContext(),"binding",?Toast.LENGTH_SHORT).show();
returnmMessenger.getBinder();
}
}
再看一下Activity的代碼:
publicclassActivityMessengerextendsActivity?{
/**?向Service發(fā)送Message的Messenger對象?*/
Messenger?mService?=null;
/**?判斷有沒有綁定Service?*/
booleanmBound;
privateServiceConnection?mConnection?=newServiceConnection()?{
publicvoidonServiceConnected(ComponentName?className,?IBinder?service)?{
//?Activity已經綁定了Service
//?通過參數service來創(chuàng)建Messenger對象,這個對象可以向Service發(fā)送Message,與Service進行通信
mService?=newMessenger(service);
mBound?=true;
}
publicvoidonServiceDisconnected(ComponentName?className)?{
mService?=null;
mBound?=false;
}
};
publicvoidsayHello(View?v)?{
if(!mBound)return;
//?向Service發(fā)送一個Message
Message?msg?=?Message.obtain(null,?MessengerService.MSG_SAY_HELLO,0,0);
try{
mService.send(msg);
}catch(RemoteException?e)?{
e.printStackTrace();
}
}
@Override
protectedvoidonCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protectedvoidonStart()?{
super.onStart();
//?綁定Service
bindService(newIntent(this,?MessengerService.class),?mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protectedvoidonStop()?{
super.onStop();
//?解綁
if(mBound)?{
unbindService(mConnection);
mBound?=false;
}
}
}
注意:以上寫的代碼只能實現從Activity向Service發(fā)送消息,如果想從Service向Activity發(fā)送消息,只要把代碼反過來寫就可以了。
使用AIDL
這個方法略,如果知道上面兩種方法,這個方法基本很少會用到。