本篇文章主要介紹以下幾個知識點:
- Android IPC簡介骄蝇;
- Android 中的多進程模式 ;
- IPC基礎(chǔ)概念介紹 魄眉。
2.1 Android IPC簡介
IPC 是 Inter-Process Communication 的縮寫,含義是進程間通信或跨進程通信郑兴,指兩個進程間進行數(shù)據(jù)交互的一個過程。
線程:是CPU調(diào)度的最小單元贝乎,同時是一種有限的系統(tǒng)資源
進程:一般指一個執(zhí)行單元情连,在PC和移動設(shè)備上指一個程序或一個應(yīng)用
一個進程可包含多個線程,進程和線程是包含與被包含的關(guān)系览效。
最簡單的情況下蒙具,一個進程中可以只有一個線程,即主線程朽肥,在 Android 里主線程也叫 UI 線程禁筏,在 UI 線程里才能操作界面元素。
若一個進程中要執(zhí)行大量耗時的任務(wù)衡招,把這些任務(wù)放在主線程中去執(zhí)行就會造成界面無法響應(yīng)篱昔,在 Android 中叫做 ANR (Application Not Responding),即應(yīng)用無響應(yīng),這時要把這些耗時的任務(wù)放在線程中即可州刽。
2.2 Android 中的多進程模式
Android 中通過給四大組件指定 android:process
屬性空执,可輕易開啟多進程模式,但實際使用過程中卻暗藏殺機穗椅,甚至弊大于利辨绊。
2.2.1 開啟多進程模式
正常情況下,在 Android 中多進程是指一個應(yīng)用中存在多個進程的情況匹表,這里不討論兩個應(yīng)用之間的情況门坷。
在 Android 中使用多進程只有一種方法,那就是給四大組件指定 android:process袍镀,即無法給一個線程或?qū)嶓w類指定其運行時所在的進程(通過 JNI 在 native 層去 fork 一個新的進程默蚌,是一種非常規(guī)的創(chuàng)建多進程方式,暫不考慮此方式)苇羡,如下:
<!-- 沒指定 process 屬性绸吸,運行在默認進程中 -->
<activity
android:name=".chapter02.Chapter02Activity"/>
<!-- 當(dāng) SecondActivity 啟動時,系統(tǒng)會為它創(chuàng)建一個單獨的進程设江,
進程名:com.wonderful.androidartexplore:remote -->
<activity
android:name=".chapter02.SecondActivity"
android:process=":remote"/>
<!-- 當(dāng) ThridActivity 啟動時锦茁,系統(tǒng)也會為它創(chuàng)建一個單獨的進程,
進程名:com.wonderful.androidartexplore.remote -->
<activity
android:name=".chapter02.ThirdActivity"
android:process="com.wonderful.androidartexplore.remote"/>
上面分別為 SecondActivity 和 ThirdActivity 指定了 process
屬性叉存,當(dāng)運行程序時發(fā)現(xiàn)進程列表末尾存在三個進程码俩,說明成功的開啟了多進程。
上面 SecondActivity 和 ThirdActivity 的進程名分別為:remote 和 包名.remote鹉胖,有兩方面區(qū)別:
1. “:”的含義是指在當(dāng)前的進程名前附加上包名握玛,是一種簡單寫法够傍,SecondActivity 的完整進程名為 com.wonderful.androidartexplore:remote
甫菠,而 ThirdActivity 中的申明方式,是一種完整的命名方式冕屯,不會附加包名信息寂诱;
2. 進程以”:“開頭的屬于當(dāng)前應(yīng)用的私有進程,其他應(yīng)用的組件不可以和它跑在同一個進程中安聘,而進程名不以”:“開頭的進程屬于全局進程痰洒,其他應(yīng)用通過ShareUID方式可以和它跑在同一進程中。
2.2.2 多進程模式的運行機制
所有運行在不同進程中的四大組件浴韭,只要它們之間需要通過內(nèi)存來共享數(shù)據(jù)丘喻,都會共享失敗,這也是多進程帶來的主要影響念颈,正常情況下四大組件中間不可能不通過一些中間層來共享數(shù)據(jù)泉粉,那么通過簡單地指定進程名來開啟多進程都會無法正確運行。
當(dāng)然,特殊情況下嗡靡,某些組件之間不需要共享數(shù)據(jù)跺撼,這時可直接指定 android:process
屬性來開啟多進程,但這種場景不常見讨彼,幾乎所有情況都需要共享數(shù)據(jù)歉井。
一般來說,使用多進程會造成如下幾方面的問題:
(1)靜態(tài)成員和單例模式完全失效哈误。
(2)線程同步機制完全失效哩至。
(3)SharedPreferences的可靠性下降。
(4)Application會多次創(chuàng)建黑滴。
對于問題1憨募,Android 為每個進程都分配一個獨立的虛擬機,不同的虛擬機在內(nèi)存上有不同的地址空間袁辈,這就導(dǎo)致在不同的虛擬機中訪問同一個類的對象會產(chǎn)生多份副本菜谣。
對于問題2,本質(zhì)上和第一個問題是類似的晚缩,既然都不是一塊內(nèi)存了尾膊,那么不管是鎖對象還是鎖全局類都無法保證線程同步,因為不同進程鎖都不是同一個對象荞彼。
對于問題3冈敛,是因為SharedPreferences
不支持兩個進程同時去執(zhí)行寫操作,否則會導(dǎo)致一定幾率的數(shù)據(jù)丟失鸣皂,這是因為SharedPreferences
底層是通過讀/寫XML文件來實現(xiàn)的抓谴,并發(fā)讀/寫都有可能出問題
對于問題4,當(dāng)一個組件跑在一個新的進程中時寞缝,由于系統(tǒng)要在創(chuàng)建新的進程同時分配獨立的虛擬機癌压,此過程就是啟動一個應(yīng)用的過程,相當(dāng)于系統(tǒng)又把這個應(yīng)用重啟動了一遍荆陆,從而創(chuàng)建新的 Application滩届。
或者說,運行在同一個進程中的組件是屬于同一個虛擬機和同一個 Application 的被啼,同理帜消,運行在不同進程中的組件是屬于兩個不同的虛擬機和 Application 的。
2.3 IPC 基礎(chǔ)概念介紹
IPC 中的一些基礎(chǔ)概念浓体,主要包含三方面內(nèi)容:Serializable
接口泡挺,Parcelable
接口以及Binder
。
Serializable
和 Parcelable
接口可以完成對象的序列化過程命浴,當(dāng)需要通過 Intent
和 Binder
傳輸數(shù)據(jù)時就需要用到它們娄猫。
當(dāng)把對象持久化到存儲設(shè)備上或通過網(wǎng)絡(luò)傳輸給其他客戶端時,也需要使用 Serializable
來完成對象的持久化。