一.概念
IPC(Inter-Process Communication)意為進程間通信或者跨進程通信。
首選我們需要弄懂什么是進程?和我們常提及的線程又是什么關系?
線程:CPU調(diào)度的最小單元,同時線程是一種有限的系統(tǒng)資源瞧剖。
進程:一般指一個執(zhí)行單元,在PC和移動設備上指一個程序或一個應用可免。
一個進程可以包含多個線程抓于,因此進程與線程是包含與被包含的關系。
Android是基于Linux內(nèi)核的移動操作系統(tǒng)浇借,它有著屬于自己的進程間通信方式捉撮,而其中,最有特色的進程間通信方式就是Binder了妇垢。
二.Android中的多進程模式
1.開啟多進程
在Android(此處指一個應用)中使用多進程只有一種方法巾遭,就是給四大組件在AndroidManifest中指定android:process屬性肉康,除此之外別無他法。
2.運行機制
Android為每一個應用分配了獨立的虛擬機灼舍,或者說為每個進程都分配了獨立的虛擬機吼和,不同的虛擬機在內(nèi)存分配上有不同的地址空間,這就導致在不同的虛擬機中訪問同一個類的對象會產(chǎn)生多份副本骑素。
一般來說炫乓,使用多進程會造成如下幾方面的問題:
(1)靜態(tài)成員和單例模式完全失效
(2)線程同步機制完全失效
(3)SharedPreferences的可靠性下降
(4)Application會多次創(chuàng)建
運行在不同進程中的組件是屬于不同的虛擬機和Application的。
三.IPC介紹
1.Serialiazable接口
Serializable是Java所提供的的一個序列化接口献丑,它是一個空接口末捣,為對象提供標準的序列化和反序列化操作。
通常情況我們只需要讓一個類實現(xiàn)Serializable接口并聲明一個serialVersionUID就可以讓這個類的對象實現(xiàn)序列化创橄。
public class User implements Serializable {
private static final long serialVersionUID = 123456789L;
public int id;
public String name;
......
}
其中serialVersionUID用來輔助序列化和反序列化過程箩做,原則上序列化后的數(shù)據(jù)中的serialVersionUID只有和當前類的serialVersionUID相同才能夠正常的被反序列化。
如果不指定serialVersionUID的話妥畏,系統(tǒng)會通過計算當前類的hash值邦邦,自動賦給
serialVersionUID。通過手動指定serialVersionUID醉蚁,可以很大程度上避免反序列化過程的失敗圃酵。
如:在版本升級后,可能刪除或添加了類中的成員變量馍管,此時仍能成功的反序列化。
2.Parcelable接口
Parcelable也是一個接口薪韩,只要實現(xiàn)這個接口确沸,一個類的對象就可以實現(xiàn)序列化并可以通過Intent和Binder傳遞。
public class User implements Parcelable {
public int id;
public String name;
public int age;
public User() {
}
//幾乎所有情況下都返回0俘陷,可以忽略該方法罗捎。
@Override
public int describeContents() {
return 0;
}
//實現(xiàn)序列化
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.name);
dest.writeInt(this.age);
}
//實現(xiàn)反序列化
protected User(Parcel in) {
this.id = in.readInt();
this.name = in.readString();
this.age = in.readInt();
}
public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
//調(diào)用反序列化方法
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
Android系統(tǒng)中Intent、Bundle拉盾、Bitmap等類已經(jīng)實現(xiàn)了Parcelable接口桨菜。
Serializable和Parcelable比較:
Serializable是Java中的序列化接口,其使用起來簡單但是開銷很大捉偏。
Parcelable是Android中的序列化方式倒得,效率更高,缺點是使用較為麻煩夭禽。
此外霞掺,Parcelable主要用在內(nèi)存序列化上;通過序列化實現(xiàn)存儲和網(wǎng)絡傳輸還是建議用Serializable讹躯。
3.Binder
Binder是Android中的一個類菩彬,它實現(xiàn)了IBinder接口缠劝。
- 從IPC的角度來說,Binder是Android中的一種跨進程通信方式骗灶。
- 從Android Framework角度來說惨恭,Binder是ServiceManager連接各種-Manager(ActivityManager、WindowManager等等)和相應ManagerService的橋梁耙旦。
- 從Android應用層來說脱羡,Binder是客戶端和服務端進行通信的媒介,如Activity綁定Service母廷。
Binder運行機制:
服務端中的Service給與其綁定的客戶端提供Binder對象轻黑,客戶端通過AIDL接口中的asInterface()將這個Binder對象轉(zhuǎn)換為代理Proxy,并通過它發(fā)起RPC請求琴昆∶ケ桑客戶端發(fā)起請求時會掛起當前線程,并將參數(shù)寫入data然后調(diào)用transact()业舍,RPC請求會通過系統(tǒng)底層封裝后由服務端的onTransact()處理抖拦,并將結(jié)果寫入reply,最后返回調(diào)用結(jié)果并喚醒客戶端線程舷暮。
四.Android中的IPC
AIDL文件的本質(zhì)是系統(tǒng)為我們提供了一種快速實現(xiàn)Binder的工具态罪,僅此而已。