今天總結下 Android 多進程運行機制以及 IPC 介紹,內容如下:
- Android 中的進程
- Android IPC 介紹
- 開啟多進程模式
- Android 多進程運行機制
Android 中的進程#
首先進程可以理解為獨立運行的程式,當某個程式啟動時,系統將會為該程式創建一個進程,並為其分配所需的系統資源,同時將該進程添加到進程就緒隊列中,進程調動程式負責運行哪一個進程。
Android 中的應用程式可以為一個進程,也可以配置成多進程,每個進程都在自己獨立的空間中運行,Android 為每個進程分配一個虛擬機,不同的虛擬機在內存分配上有不同的地址空間,不同的進程自然涉及到進程間通訊。
Android 中的進程如下:
- 前臺進程:可與用戶直接交互或與前臺綁定的 Service 所在的進程;
- 可見進程:用戶可見但是不可點擊;
- 服務進程:後臺執行的 Service 所在的進程;
- 後臺進程:相對於前臺進程而言的進程;
- 空進程:理解為一種緩存意義上的進程,系統隨時可以選擇回收空進程。
其優先級為前臺進程 > 可見進程 > 服務進程 > 後臺進程 > 空進程。
Android IPC 介紹#
IPC (Inter-Process Communication) 指的是進程間通訊或跨進程通訊,任何一個操作系統都需要相應的 IPC 機制來完成進程間通訊,如 Windows 上可以通過剪貼簿、管道等來完成進程間通訊,Linux 上可以通過信道、共享內存、信號量來進行進程間通訊。Android 雖然基於 Linux,但是為了適應移動端的特點,專門提供了一種進程間通訊方式 Binder,所以說到 Android 中的 IPC 機制,一般指的就是 Android 中的 Binder 機制。
IPC 使用場景:
- 某些應用自身需要採用多進程模式,如在 Android 中對一個應用獲取的最大內存做了限制,為了使自己的應用獲取更多內存空間而將一些模塊放在獨立進程中,此時模塊之間的交互就需要進程間通訊來完成;
- 應用本身需要跨進程與其他應用交互,無論是使用 ContentProvider 還是 AIDL 都屬於 IPC 的範疇,如在 Android 機頂盒 IPTV 中間件中就有大量使用。
注意:Android 對應用內存的限制不同廠商不同,默認分配的初始內存是 16M,具體配置在 system/build.prop 文件中。
開啟多進程模式#
Android 中開啟多進程是在四大組件中配置 android:process
屬性來開啟多進程,配置時可以配置成私有進程和全局進程,如下:
<!--私有進程-->
<!--com.manu.progress:remote-->
<activity
android:name="com.manu.process.SampleActivity"
android:process=":remote"/>
<!--全局進程-->
<!--com.manu.remote-->
<activity
android:name="com.manu.process.SampleActivity"
android:process="com.manu.remote"/>
如果配置成私有進程,則其他應用的組件不可與其跑在同一進程中,如果配置全局進程,則可以將兩個應用設置成相同的 ShareUID 將兩個應用的組件運行在同一進程中,除此之外這兩個應用的簽名也得相同,這樣將可將兩個應用的組件運行在同一進程中,且可以共享私有數據如 data 目錄等。
那麼怎麼將兩個應用的組件配置在同一進程呢?
- 兩個應用設置相同的 ShareUID
- 兩個應用的兩個組件的進程設置成進程名相同的全局進程
- 兩個應用簽名相同
測試過程中發現,如果一個進程已經啟動了,在啟動一個配置同一進程的組件時,第二個應用程式會異常退出,這一點還需閱讀源碼進一步了解原因.
- 怎麼將兩個應用的組件配置在同一進程呢?
Android 多進程運行機制#
Android 為每個進程分配一個獨立的虛擬機,不同的虛擬機在內存分配上有不同的地址空間,這就導致在不同的虛擬機中訪問同一個類的對象會產生多份副本,也就是說在兩個進程中存在著同一個類的兩個副本,這兩個類互不干擾,修改一個不會影響另一個,這就導致了一個問題,即運行在不同進程中的四大組件,只要它們之間通過內存來共享數據,都會共享失敗,多進程造成的問題如下:
- 靜態成員和單例模式完全失效
多進程中在著一個類的多個副本,修改互不影響,自然無法生效;
- 線程同步機制完全失效
線程同步機制鎖住的不是一個對象,自然無法生效;
- SharePreference 的可靠性下降
SharePreference 雖然可以設置 MODE_MULTI_PROCESS 支持多進程,但是並不推薦使用,因為在某些版本上不生效,在 API 23 之後已被廢棄,所以使用 MODE_MULTI_PROCESS 支持 SharePreference 多進程是不靠譜的,解決方案是使用 ContentProvider 作為中間層來使的 SharePreferences 來支持多進程。
具體就是其他進程通過 ContentProvider 來訪問另一個進程,而數據是存儲在 SharePreference 中的,可通過 Contentprovider 實現增刪查改來對數據進行操作。
- Application 多次創建
當一個組件運行到一個新的進程時,創建進程的過程實際上就是一個應用啟動的過程,自然會使得 Application 多次創建,可以這樣理解為運行在同一進程中的組件是屬於同一個虛擬機和同一個 Application 的,不同進程中的組件屬於多個虛擬機和 Application。
Application 的 onCreate 方法一般用來初始化操作,如果多次調用 Application 的 onCreate 方法,為避免出錯,可根據進程名判斷再進行相關初始化。
上文是對 Android 多進程運行機制及 IPC 的介紹,Android 中 IPC 方式實現方式有 Bundle、文件傳輸、AIDL、Messenger、ContentProvider 等方式,這部分內容將在後續進行整理和分享。