Android IPC簡介
IPC是Inter-Process Communication的縮寫,含義就是程式間通訊或者跨程式通訊,是指兩個程式之間進行資料交換的過程。那麼什麼是程式,什麼是執行緒,程式和執行緒是兩個截然不同的概念。在作業系統中,執行緒是CPU排程的最小單元,同時執行緒是一種有限的系統資源。而程式指的一個執行單元,在PC和移動裝置上指的是一個程式或者一個應用。一個程式可以包含多個執行緒,因此程式和執行緒是包含被包含的關係,最簡單情況下,一個程式可以只有一個執行緒,即主執行緒,在Android裡面也叫UI執行緒,在UI執行緒裡才能操作介面元素。
那麼在Android中,有特色的程式間通訊方式就是Binder了,通過Binder可以輕鬆實現程式間通訊。除了Binder,Android還支援Socket,通過Socket也可以實現任意兩個終端之間的通訊,當然一個裝置上的兩個程式之間通過Socket通訊自然也是可以的。
說到IPC的使用場景就必須提到多程式,只有面對多程式這種場景下,才需要考慮程式間通訊。所有執行在不同程式中的四大元件,只要它們之間需要通過記憶體來共享資料,都會共享失敗,這也是多程式所帶來的主要影響。正常情況下,四大元件中間不可能不通過一些中間層來共享資料,那麼通過簡單地指定程式名來開啟多程式都會無法正確執行。一般來說,使用多程式會造成如下幾方面的問題:
- 靜態成員和單例模式完全失效
- 執行緒同步機制完全失效
- SharedPreferences的可靠性下降
- Application會多次建立
為了解決這個問題,系統提供了很多跨程式通訊方法,雖然說不能直接地共享記憶體,但是通過跨程式通訊我們還是可以實現資料互動。實現跨程式通訊的方式有很多,比如通過Intent來傳遞資料,共享檔案SharedPreference,基於Binder的Messenger和AIDL以及Socket等。
IPC基礎概念介紹
Serializable介面
Serializable是Java提供的一個序列化介面,它是一個空介面,為物件標準的序列化和反序列化操作。使用Serializable來實現序列化相當簡單,一句話即可。
public class User implements Serializable {
private static final long seriaVersionUID = 519067123721295773L
}
Parcelable介面
Parcel內部包裝了可序列化的資料,可以在Binder中自由傳輸,在序列化過程中需要實現的功能有序列化、反序列化和內容描述序列化功能有writeToParcel
方法來完成,最終是通過Parcel中的一系列write
方法來完成的。用法如下:
public class MyParcelable implements Parcelable {
// You can include parcel data types
private int mData;
private String mName;
// We can also include child Parcelable objects. Assume MySubParcel is such a Parcelable:
private MySubParcelable mInfo;
// This is where you write the values you want to save to the `Parcel`.
// The `Parcel` class has methods defined to help you save all of your values.
// Note that there are only methods defined for simple values, lists, and other Parcelable objects.
// You may need to make several classes Parcelable to send the data you want.
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
out.writeString(mName);
out.writeParcelable(mInfo, flags);
}
// Using the `in` variable, we can retrieve the values that
// we originally wrote into the `Parcel`. This constructor is usually
// private so that only the `CREATOR` field can access.
private MyParcelable(Parcel in) {
mData = in.readInt();
mName = in.readString();
mInfo = in.readParcelable(MySubParcelable.class.getClassLoader());
}
public MyParcelable() {
// Normal actions performed by class, since this is still a normal object!
}
// In the vast majority of cases you can simply return 0 for this.
// There are cases where you need to use the constant `CONTENTS_FILE_DESCRIPTOR`
// But this is out of scope of this tutorial
@Override
public int describeContents() {
return 0;
}
// After implementing the `Parcelable` interface, we need to create the
// `Parcelable.Creator<MyParcelable> CREATOR` constant for our class;
// Notice how it has our class specified as its type.
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
// This simply calls our new constructor (typically private) and
// passes along the unmarshalled `Parcel`, and then returns the new object!
@Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
// We just need to copy this and change the type to match our class.
@Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
Serializable和Parcelable區別
Serializable是Java中的序列化介面,其使用起來簡單但是開銷很大,在序列化和反序列化過程中需要大量的I/O操作。而Parcelable是Android中的序列化方式,因此更適合用在Android平臺上,它的缺點就是使用起來稍微麻煩點,但是它的效率很高。
Binder
直觀來說,Binder是Android中的一個類,它實現了IBinder介面。從IPC角度來說,Binder是Android中的一種跨程式通訊方式,Binder還可以理解為一種虛擬的物理裝置,它的裝置驅動是/dev/binder,該通訊方式在Linux中沒有。從Android Framework角度來說,Binder是ServiceManager連線各種Manager(ActivityManager、WindowManager等等)和相應ManagerService的橋樑。從Android應用層來說,Binder是客戶端和服務端進行通訊的媒介,當bindService的時候,服務端會返回一個包含了服務端業務呼叫的Binder物件,通過Binder物件,客戶端就可以獲取服務端提供的服務或者資料,這裡的服務包括普通服務和基於AIDL的服務。
Android中的IPC方式
使用Bundler
我們知道,四大元件中三大元件(activity、service、receiver)都是支援在Intent中傳遞Bundle資料的,由於Bundle實現了Parcelable介面,所以它可以方便地在不同的程式間傳輸。
使用檔案共享
共享檔案也是一種不錯的程式間通訊方式,兩個程式間通過讀/寫同一個檔案來交換資料,比如A程式把資料寫入檔案,B程式通過讀取這個檔案來獲取資料。
使用Messenger
Messenger可以翻譯為信使,顧名思義,通過它可以在不同程式中傳遞Message物件,在Message中放入我們需要傳遞的資料,就可以輕鬆地實現資料的程式間傳遞。Messenger是一種輕量級的IPC方案,它的底層實現是AIDL,實現Messenger有以下兩個步驟,分為服務端程式和客戶端程式。
使用AIDL
遠端服務跨程式通訊的一種方式。
使用ContentProvider
ContentProvider是Android中提供的專門用於不同應用間進行資料共享的方式,它的底層實現同樣也是Binder。
使用Socket
Socket也稱為“套接字”,是網路通訊中的概念,它分為流式套接字和使用者資料套接字兩種,分別應於網路的傳輸控制層中的TCP和UDP協議。
選用合適的IPC方式
閱讀擴充套件
源於對掌握的Android開發基礎點進行整理,羅列下已經總結的文章,從中可以看到技術積累的過程。
1,Android系統簡介
2,ProGuard程式碼混淆
3,講講Handler+Looper+MessageQueue關係
4,Android圖片載入庫理解
5,談談Android執行時許可權理解
6,EventBus初理解
7,Android 常見工具類
8,對於Fragment的一些理解
9,Android 四大元件之 " Activity "
10,Android 四大元件之" Service "
11,Android 四大元件之“ BroadcastReceiver "
12,Android 四大元件之" ContentProvider "
13,講講 Android 事件攔截機制
14,Android 動畫的理解
15,Android 生命週期和啟動模式
16,Android IPC 機制
17,View 的事件體系
18,View 的工作原理
19,理解 Window 和 WindowManager
20,Activity 啟動過程分析
21,Service 啟動過程分析
22,Android 效能優化
23,Android 訊息機制
24,Android Bitmap相關
25,Android 執行緒和執行緒池
26,Android 中的 Drawable 和動畫
27,RecylerView 中的裝飾者模式
28,Android 觸控事件機制
29,Android 事件機制應用
30,Cordova 框架的一些理解
31,有關 Android 外掛化思考
32,開發人員必備技能——單元測試