在android開發中一個App很少情況下是隻具備一個進程的,因此多個進程存活在同一個App中非常正常,這對減少app的pss也很有幫助。出現多個進程,也不得不談及跨進程通信,目前主要有以下幾種跨進程通信方式:
1.Bundle方式,該方式一般用於Service,Activity,BroadcastReceiver組件間通信,當進程A的ActivityA,想傳個東西給進程B的ActivityB,此時就可以採用Bundle方式傳遞,但是有個前提就是Bundle支持的數據類型有限,有時候需要對數據進行Parcelable或Serializable;但有時候你覺得序列化很麻煩,IntentService策略也是一種選擇,將獲取ActivityB所要用到的數據處理邏輯讓IntentService來處理,而IntentService也設置在進程B中,這樣在ActivityA中啓動下IntentService,結果馬上就出來了。
2.文件共享,該方法簡單,但是並不適合高併發場景,儘管在android中多個進程對文件進行讀寫沒有報錯,但是獲取數據可能存在問題,對併發訪問實時性不是很高的,可以考慮下這種方法;
3.Messenger方式,注意不是Message,該方式儘管底層邏輯也是AIDL模式,功能一般,對高併發情景處理也不是很樂觀,當你需要服務器和客戶端交換些數據時,可以考慮下這種方法;
4.ContentProvider,這本就是android的組件,效率也不要考慮,不過也可以看成是約束性AIDL,主要提供CRUD操作,支持一對多進程間通信;
5.Socket,有個網絡經驗的自然不會陌生,但其實現細節有點繁瑣,也可以適用於網絡數據交換;
6.SharedPreference,這個東西儘管大家經常用,但他不適合跨進程傳遞數據,如果喜歡它了,用ContentProvider改造下即可,重點實現getType方法。
7.AIDL, 這位大神終於出來了,這無疑是大家首先想到的跨進程方式,採用它,客戶端只要bind上服務端,就可以調用服務端提供的功能,其實呢,通過各接口,服務端還是可以主動調用客戶端方法
具體細節見代碼:
package com.example.testservice;
import com.example.testservice.ITestCallback;
interface test {
int getBookId();
void setCallBack(ITestCallback callback);
}
package com.example.testservice;
interface ITestCallback {
void addName(String name);
}
客戶端綁定邏輯:
<pre name="code" class="html">private DeathRecipient mDeathRecipient = new DeathRecipient() {
@Override
public void binderDied() {
if(idTest != null){
idTest.asBinder().unlinkToDeath(mDeathRecipient, 0);
idTest = null;
// bindServiceImpl();
}
}
};
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
//ignore
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
idTest = test.Stub.asInterface(service);
setCallBack();
try {
idTest.asBinder().linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private void setCallBack(){
try {
idTest.setCallBack(new ITestCallback.Stub() {
@Override
public void addName(String name) throws RemoteException {
}
});
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}