Android多進程機制(一)IPC基礎(chǔ)概念

Android IPC 基礎(chǔ)概念

多進程應(yīng)用場景

  1. 應(yīng)用自身需要采用多進程模式來實現(xiàn)含滴。
  • 有些模塊需要運行在單獨的線程中俊柔。
  • 需要加大一個應(yīng)用可使用的內(nèi)存坎怪,通過多進程來獲取多份內(nèi)存空間敦迄。
//獲取應(yīng)用限制的內(nèi)存大小和進程限制的內(nèi)存大小
//我設(shè)備測試的是 heapGrowthLimit: 256m 斧散,heapSize: 512m
ActivityManager activityManager =(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
int heapGrowthLimit = activityManager.getMemoryClass();// 單個應(yīng)用可用最大內(nèi)存
int heapSize = activityManager.getLargeMemoryClass();//單個進程可用的最大內(nèi)存
Log.d(TAG, "heapGrowthLimit: " + heapGrowthLimit + "\nheapSize: " + heapSize);
  1. 需要向其他應(yīng)用獲取數(shù)據(jù)玻驻,也就是跨進程訪問數(shù)據(jù)悼凑。

如何跑在同一進程

  1. 兩個應(yīng)用能跑在同一進程的前提條件是具有相同的ShareUID和簽名。
  2. 具有相同ShareUID并且簽名相同的兩個應(yīng)用璧瞬,可以共享對方私有數(shù)據(jù)户辫,比如data目錄、組件信息等嗤锉。
  3. 如果ShareUID相等渔欢、簽名相同且跑在同一進程中,那么除了能共享data目錄瘟忱、組件信息等奥额,還能共享內(nèi)存數(shù)據(jù)。

開啟多進程的方式

使一個應(yīng)用開啟多進程模式访诱,有以下兩種方式:

  1. AndroidMenifest中指定android:process屬性垫挨。
  2. 通過JNI在native層去fork一個新進程。

第二種不常用触菜,暫時只看第一種九榔。AndroidMenifest中沒有給某個組件指定process屬性時默認(rèn)運行默認(rèn)進程,默認(rèn)進程的名字為程序包名涡相。如果要指定哲泊,有兩種方式。

android:process=":jtt"
android:process="com.utte.test.jtt"

兩種方式還是有區(qū)別的:

  • 第一種分號的意思是進程名前面加上當(dāng)前包名催蝗,進程名為"com.utte.test:jtt"切威。
  • 第二種的進程名直接就是屬性值,進程名為"com.utte.test.jtt"生逸。
  • 第一種屬于當(dāng)前應(yīng)用的私有進程牢屋,其他應(yīng)用的組件不能與其跑在同一進程中。
  • 第二種為全局進程槽袄,其他應(yīng)用可通過ShareUID的方式與其跑在同一進程中。

多進程運行機制

Android為每個應(yīng)用也就是說為每個進程都分配了一個獨立的虛擬機锋谐,不同的虛擬機在內(nèi)存分配上有不同的地址空間遍尺,就導(dǎo)致在不同的虛擬機中訪問同一個類的對象時會產(chǎn)生多份副本。

所有運行在不同進程中的四大組件都不能通過共享內(nèi)存來共享數(shù)據(jù)涮拗,所以會造成以下影響:

  1. 靜態(tài)成員和單例模式完全失效

會分配不同虛擬機乾戏,所以會產(chǎn)生多個對象副本迂苛。

  1. 線程同步機制完全失效

不同進程中的對象不是同一個對象,所以加鎖達(dá)不到效果鼓择。

  1. SharePreferences的可靠性降低

SharePreferences不支持兩個進程同時進行寫操作三幻,會導(dǎo)致一定幾率數(shù)據(jù)丟失,SharePreferences底層是通過讀寫XML來實現(xiàn)的呐能,并且內(nèi)存中會有緩存念搬。

  1. Application會多次創(chuàng)建

當(dāng)一個組件跑在新進程中時,系統(tǒng)會在創(chuàng)建新進程時同時分配獨立的虛擬機令杈,這個過程是一個應(yīng)用啟動的過程锯岖,相當(dāng)于把應(yīng)用重新啟動了一次纫谅,自然Application也會重新創(chuàng)建。

運行在兩個進程中的兩個組件會擁有獨立的虛擬機爷恳、獨立的Application、獨立的內(nèi)存空間象踊。

它們也就相當(dāng)于是兩個應(yīng)用擁有相同的ShareUID和簽名温亲,但不跑在同一進程中,它們可以訪問對方數(shù)據(jù)杯矩,但是不能通過共享內(nèi)存的方式栈虚。雖然不能共享內(nèi)存了,但是還有很多方式可以實現(xiàn)跨進程的數(shù)據(jù)交互菊碟。

多進程通信的主要方式

  • Binder
  • Bundle
  • 文件共享
  • AIDL
  • Messenger
  • ContentProvider
  • Socket

Bundle节芥、文件共享、Socket比較簡單逆害,也基本都使用過头镊,其他的都與Binder有關(guān),包括ContentProvider魄幕,它的底層其實也是Binder相艇。

序列化

我們傳輸?shù)臄?shù)據(jù)必須能夠被序列化,比如基本類型纯陨、實現(xiàn)了Parcelable接口的對象坛芽、實現(xiàn)Serializable接口的對象以及Android支持的一些特殊對象。

Serializable接口

通過Serializable使一個對象實現(xiàn)序列化:

  1. 類實現(xiàn)Serializable接口
  2. 聲明serialVersionUID (非必需)

類定義:

public class Book implements Serializable {
    private static final long serialVersionUID = 199898L;
    \\...
}

序列化使用ObjectOutputStream.writeObject()翼抠,反序列化使用ObjectInputStream.read()咙轩。

序列化后的數(shù)據(jù)中的serialVersionUID只有和當(dāng)前類的serialVersionUID相同才可以被正常的反序列化。如果不手動指定serialVersionUID阴颖,系統(tǒng)就會根據(jù)類信息計算hash值賦值給serialVersionUID活喊。這樣的話如果在序列化后對類進行了一些更改,在沒有指定serialVersionUID的情況下量愧,會反序列化失敗報異常钾菊,如果指定了帅矗,在非毀滅性改變的前提下,程序會盡可能最大限度的恢復(fù)數(shù)據(jù)煞烫。

Parcelable接口

更詳細(xì)的內(nèi)容可以看這篇博客浑此,Android中Serializable和Parcelable序列化對象詳解

Parcelable的用法如下滞详,需要實現(xiàn)Parcelable序列化凛俱、反序列化、描述三個邏輯茵宪。

public class User implements Parcelable {

    private boolean isMale;
    private Book mBook; //Serializable對象
    private Bag mBag;   //Parcelable對象

    public User(boolean isMale, Book book, Bag bag) {
        this.isMale = isMale;
        mBook = book;
        mBag = bag;
    }

    //描述
    @Override
    public int describeContents() {
        return 0;
    }
    
    //序列化
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(isMale ? 1 : 0);
        out.writeSerializable(mBook);
        out.writeParcelable(mBag, 0);
    }

    //反序列化
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
    
    //給反序列化創(chuàng)建對象調(diào)用
    private User(Parcel in) {
        isMale = in.readInt() == 1;
        mBook = (Book) in.readSerializable();
        mBag = in.readParcelable(Bag.class.getClassLoader());
    }
    
}

  • Parcel為內(nèi)部包裝了可序列化的數(shù)據(jù)最冰。
  • writeToParcel()的flag如果為1就表示當(dāng)前對象需要作為返回值返回,不能立即釋放稀火,0表示不需要暖哨,幾乎所有情況都是0。
  • describeContents()返回0表示不含文件描述符凰狞,存在文件描述符時返回1篇裁,幾乎所有時候都應(yīng)該返回0。

獲取到文件描述符可以完成所有文件相關(guān)的操作赡若,因為作用大达布,所以為了防止泄露,需要禁止在Bundle傳輸Parcel時包含文件描述符逾冬,如果通過Parcel中包含ParcelFileDescriptor的Bundle使用時就會拋出IllegalArgumentException黍聂。這個值是在系統(tǒng)內(nèi)部進行安全保護所使用的,其他情況下填0即可身腻。

Serializable和Parcelable比較

Serializable Parcelable
使用比較簡單 使用稍微麻煩
IO流形操作产还,性能較低 基于內(nèi)存操作,效率高

Parcelable主要用于內(nèi)存序列化嘀趟。Serializable主要用于序列化到存儲設(shè)備或網(wǎng)絡(luò)傳輸脐区。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市她按,隨后出現(xiàn)的幾起案子牛隅,更是在濱河造成了極大的恐慌,老刑警劉巖酌泰,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媒佣,死亡現(xiàn)場離奇詭異,居然都是意外死亡陵刹,警方通過查閱死者的電腦和手機丈攒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來授霸,“玉大人巡验,你說我怎么就攤上這事〉舛” “怎么了显设?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辛辨。 經(jīng)常有香客問我捕捂,道長,這世上最難降的妖魔是什么斗搞? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任指攒,我火速辦了婚禮,結(jié)果婚禮上僻焚,老公的妹妹穿的比我還像新娘允悦。我一直安慰自己,他們只是感情好虑啤,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布隙弛。 她就那樣靜靜地躺著,像睡著了一般狞山。 火紅的嫁衣襯著肌膚如雪全闷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天萍启,我揣著相機與錄音总珠,去河邊找鬼。 笑死勘纯,一個胖子當(dāng)著我的面吹牛局服,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屡律,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼腌逢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了超埋?” 一聲冷哼從身側(cè)響起搏讶,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霍殴,沒想到半個月后媒惕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡来庭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年妒蔚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡肴盏,死狀恐怖科盛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菜皂,我是刑警寧澤贞绵,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站恍飘,受9級特大地震影響榨崩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜章母,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一母蛛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乳怎,春花似錦彩郊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椿胯,卻和暖如春筷登,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哩盲。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工前方, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人廉油。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓惠险,卻偏偏與公主長得像,于是被迫代替她去往敵國和親抒线。 傳聞我的和親對象是個殘疾皇子班巩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容