Android進(jìn)程間通信全解析

一.概念

IPC(Inter-Process Communication)意為進(jìn)程間通信或者跨進(jìn)程通信。

首選我們需要弄懂什么是進(jìn)程?和我們常提及的線程又是什么關(guān)系?
線程:CPU調(diào)度的最小單元,同時(shí)線程是一種有限的系統(tǒng)資源。
進(jìn)程:一般指一個(gè)執(zhí)行單元,在PC和移動(dòng)設(shè)備上指一個(gè)程序或一個(gè)應(yīng)用。
一個(gè)進(jìn)程可以包含多個(gè)線程,因此進(jìn)程與線程是包含與被包含的關(guān)系。

Android是基于Linux內(nèi)核的移動(dòng)操作系統(tǒng),它有著屬于自己的進(jìn)程間通信方式,而其中,最有特色的進(jìn)程間通信方式就是Binder了。

二.Android中的多進(jìn)程模式

1.開(kāi)啟多進(jìn)程

在Android(此處指一個(gè)應(yīng)用)中使用多進(jìn)程只有一種方法,就是給四大組件在AndroidManifest中指定android:process屬性,除此之外別無(wú)他法。

2.運(yùn)行機(jī)制

Android為每一個(gè)應(yīng)用分配了獨(dú)立的虛擬機(jī),或者說(shuō)為每個(gè)進(jìn)程都分配了獨(dú)立的虛擬機(jī),不同的虛擬機(jī)在內(nèi)存分配上有不同的地址空間,這就導(dǎo)致在不同的虛擬機(jī)中訪問(wèn)同一個(gè)類的對(duì)象會(huì)產(chǎn)生多份副本。
一般來(lái)說(shuō),使用多進(jìn)程會(huì)造成如下幾方面的問(wèn)題:
(1)靜態(tài)成員和單例模式完全失效
(2)線程同步機(jī)制完全失效
(3)SharedPreferences的可靠性下降
(4)Application會(huì)多次創(chuàng)建
運(yùn)行在不同進(jìn)程中的組件是屬于不同的虛擬機(jī)和Application的。

三.IPC介紹

1.Serialiazable接口

Serializable是Java所提供的的一個(gè)序列化接口,它是一個(gè)空接口,為對(duì)象提供標(biāo)準(zhǔn)的序列化和反序列化操作。
通常情況我們只需要讓一個(gè)類實(shí)現(xiàn)Serializable接口并聲明一個(gè)serialVersionUID就可以讓這個(gè)類的對(duì)象實(shí)現(xiàn)序列化。

public class User implements Serializable {
    
    private static final long serialVersionUID = 123456789L;
    
    public int id;
    
    public String name;

    ......
}

其中serialVersionUID用來(lái)輔助序列化和反序列化過(guò)程,原則上序列化后的數(shù)據(jù)中的serialVersionUID只有和當(dāng)前類的serialVersionUID相同才能夠正常的被反序列化。

如果不指定serialVersionUID的話,系統(tǒng)會(huì)通過(guò)計(jì)算當(dāng)前類的hash值,自動(dòng)賦給
serialVersionUID。通過(guò)手動(dòng)指定serialVersionUID,可以很大程度上避免反序列化過(guò)程的失敗。
如:在版本升級(jí)后,可能刪除或添加了類中的成員變量,此時(shí)仍能成功的反序列化。

2.Parcelable接口

Parcelable也是一個(gè)接口,只要實(shí)現(xiàn)這個(gè)接口,一個(gè)類的對(duì)象就可以實(shí)現(xiàn)序列化并可以通過(guò)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;
    }
    //實(shí)現(xiàn)序列化
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }
    
    //實(shí)現(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)實(shí)現(xiàn)了Parcelable接口。

Serializable和Parcelable比較:

Serializable是Java中的序列化接口,其使用起來(lái)簡(jiǎn)單但是開(kāi)銷(xiāo)很大。
Parcelable是Android中的序列化方式,效率更高,缺點(diǎn)是使用較為麻煩。
此外,Parcelable主要用在內(nèi)存序列化上;通過(guò)序列化實(shí)現(xiàn)存儲(chǔ)和網(wǎng)絡(luò)傳輸還是建議用Serializable。

3.Binder

Binder是Android中的一個(gè)類,它實(shí)現(xiàn)了IBinder接口。

  • 從IPC的角度來(lái)說(shuō),Binder是Android中的一種跨進(jìn)程通信方式。
  • 從Android Framework角度來(lái)說(shuō),Binder是ServiceManager連接各種-Manager(ActivityManager、WindowManager等等)和相應(yīng)ManagerService的橋梁。
  • 從Android應(yīng)用層來(lái)說(shuō),Binder是客戶端和服務(wù)端進(jìn)行通信的媒介,如Activity綁定Service。

Binder運(yùn)行機(jī)制:
服務(wù)端中的Service給與其綁定的客戶端提供Binder對(duì)象,客戶端通過(guò)AIDL接口中的asInterface()將這個(gè)Binder對(duì)象轉(zhuǎn)換為代理Proxy,并通過(guò)它發(fā)起RPC請(qǐng)求??蛻舳税l(fā)起請(qǐng)求時(shí)會(huì)掛起當(dāng)前線程,并將參數(shù)寫(xiě)入data然后調(diào)用transact(),RPC請(qǐng)求會(huì)通過(guò)系統(tǒng)底層封裝后由服務(wù)端的onTransact()處理,并將結(jié)果寫(xiě)入reply,最后返回調(diào)用結(jié)果并喚醒客戶端線程。

Binder運(yùn)行機(jī)制.png

四.Android中的IPC

各種方式IPC比較圖.png

AIDL文件的本質(zhì)是系統(tǒng)為我們提供了一種快速實(shí)現(xiàn)Binder的工具,僅此而已。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 大學(xué)第一學(xué)期結(jié)束了,和室友在一起的每一天都快樂(lè)并難得。我們一起努力,我永遠(yuǎn)愛(ài)你??
    somido閱讀 356評(píng)論 0 0
  • 立在人行橫道前 綠燈未亮起 走還是不走 我選了停留 可身邊的人都漸漸走遠(yuǎn)了 我待在原地 五秒過(guò)去了 十秒又過(guò)去了 ...
    JSJSjwj閱讀 200評(píng)論 0 0
  • 越長(zhǎng)大越發(fā)現(xiàn)自己可以責(zé)怪的人越少,因?yàn)槊恳粋€(gè)人都有他的難處。 芋頭先生總在我們產(chǎn)生分歧的時(shí)候問(wèn)我:“錢(qián)真的有那么重...
    梨黎閱讀 387評(píng)論 0 0
  • 大雪過(guò)后,空氣清新,陽(yáng)光微暖,整個(gè)世界大有歲月靜好之感。
    一箋閱讀 379評(píng)論 0 1

友情鏈接更多精彩內(nèi)容