Android進程間通信IPC詳解
最近項目有進程間通信的需求,我使用的是IPC通信的方式,這是Android中很傳統的一種進程間通信的方式,在這里分享給大家。
進程間通信意義
我們為什么要使用進程間通信。我說一個場景,比如我們有兩個App,其中一個App(名字為A),有授權登陸,我們還有一個App(名字為B)可能是A的附屬App,或者同期產品,我們希望有相同的賬號,也就是A登陸了,B就自動登錄了。那么B在進入的時候需要從A中拿登陸信息,比如姓名性別,昵稱等。這時候就涉及到進程間通信了。或者B中需要一些加密算法,我們不想在B中暴露,可以把值傳給A,然后A計算完再傳遞回來。
當然還有其它場景,這里不再贅述了。
建立個工程
首先我們當然要建立一個工程,最普通的工程就可以。
服務端App
這個工程中的第一個module服務端module,也就是上面提到的A app,內容提供的app
我們在src/main中建立一個aidl文件夾:
右鍵點擊aidl文件夾,new一個aidl文件:
在里面建立一個文件,比如我們想獲取用戶信息:
interface IPeople {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String getName();
String getSex();
}
然后rebuild一下工程,這時,會在build文件夾下生成一個文件
這個文件就是aidl生成的對應的接口文件,沒有這個文件,我們之后在引用接口的時候會報錯。你不用給它轉移地方,放在這就行了。
然后我們寫一個服務Service,提供數據:
public class AidlService extends Service{
private PeopleBinder peopleBinder;
@Override
public void onCreate() {
super.onCreate();
peopleBinder = new PeopleBinder();
}
@Override
public IBinder onBind(Intent intent) {
return peopleBinder;
}
public class PeopleBinder extends IPeople.Stub
{
@Override
public String getName() throws RemoteException {
return "deep";
}
@Override
public String getSex() throws RemoteException {
return "man";
}
}
}
其中PeopleBinder是進程間傳遞數據的媒介,如果你想傳一個數據類,那么這個數據類一定要序列化。PeopleBinder實現的接口,就是剛才我們生成的那個文件中的接口。所以一定要等aidl接口文件生成我們再去寫這個類。
然后將Service注冊在AndroidManifest中,注意要加一個action,方便客戶端App啟動:
<service android:name=".AidlService">
<intent-filter>
<action android:name="deep.testaidl.AidlService"/>
</intent-filter>
</service>
要注意app要安裝到手機上啊,否則后面怎么獲取……
客戶端App
我們新建一個module,這個module就是客戶端App,也就是我們上文中提到的B App,內容索取者。
用同樣的方式建立一個aidl文件,這個aidl文件要與上面的一樣,且路徑也要一樣,如圖所示:
可以看到路徑一樣,文件名一樣,當然內容也一樣。
這樣才能保證協議一致。然后還是rebuild一下。生成對應的接口文件。
然后我們在Activity中,隨便寫一個布局(這個不多說了,與本文主旨無關),有個按鈕,有個顯示就行。
然后開始獲取用戶資料了,首先,我們需要定義一個協議接口,也就是你獲取用戶資料的接口:
private IPeople people;//協議接口
接著需要建立一個服務連接,與服務端App剛寫的那個Service進行連接通信:
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
people = IPeople.Stub.asInterface(service);//連接建立成功,讀取數據
try {
textView.setText("name ="+people.getName()+" sex="+people.getSex());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
people = null;
}
};
剛才不是寫了一個按鈕嗎,添加一個點擊事件,打開服務端寫好的Service,進行通信:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction("deep.testaidl.AidlService");
intent.setPackage("deep.testaidl");
bindService(intent,conn, Service.BIND_AUTO_CREATE);
}
});
由于我們剛才在服務連接的回調中,將用戶信息設置到了textview上,這樣就可以顯示出來了。
好了,這樣一次通信就完成了,是不是沒有想象的復雜。
總結
這種進程間通信的方式還是比較傳統的,用的也比較多,了解一下對于以后的學習很有幫助,如有其它問題可以關注我的公眾號留言給我,我會第一時間回復。
來自:https://juejin.im/post/58d39de6a22b9d00644eb60b