天天看點

Android 程序間通信(IPC機制)精煉詳解

作者:願天堂沒有代碼
今天主要對 Android 中的跨程序通信進行總結下,先梳理下裡面的涉及的一些概念
Android 程式間通信(IPC機制)精煉詳解

程序與線程

  • 程序: 系統中正在運作的一個應用程式,某個程式一旦運作就是一個程序,是資源配置設定的最小機關;
  • 線程: 程式執行的最小機關,包含在程序中,一個程序可以包含多個線程。

Android 應用中的多程序

(1)dalivk虛拟機

Android 系統的底層任務管理以及驅動都是基于 Linux 系統;一個 Android 系統其實就是一個 Linux 系統,通過 adb shell 進入連接配接的手機,就可以看到 Linux 系統的檔案系統

Android 程式間通信(IPC機制)精煉詳解

像在運作一個 Java 程式,我們知道 Linux 系統會啟動一個Java虛拟機來運作該 Java 程式,而 Android 系統是一個特殊的 Linux 系統,當啟動一個 APP,系統會為該 APP 配置設定一個 Linux 程序,而該程序中就會有一個 dalivk 虛拟機(又稱為 DVM )執行個體來運作該 APP,是以 dalivk 虛拟機就是用來運作 APP 程式

不同的APP運作在不同的程序中,對應着不同的dalivk虛拟機,就對應着不同的位址空間。反過來在一個應用内,如果新開一個程序,那麼由于系統在新開程序的時候會配置設定獨立的dalivk虛拟機,那麼對于該APP内的不同程序的執行個體是互相獨立,互不影響。

綜上:

  • 1)每個程序有獨立的dalivk虛拟機,對應着單獨的記憶體空間;
  • 2)一個應用可以有多個程序,就有多個dalivk虛拟機,對應多個記憶體空間;
  • 3)一個程序可以被多個應用通路,多個應用可以共享該程序

(2)Linux 系統組成

在 Linux 系統中,虛拟記憶體空間(我了解的就是運作軟體程式的空間,是對實體空間的映射)隻有 4G;最高的 1GB(對應虛拟位址0xC0000000到0xFFFFFFFF)被成為核心空間,而較低的 3GB(對應虛拟位址0x00000000到0xBFFFFFFF)被成為使用者空間。核心空間是Linux核心運作空間,使用者空間是應用程式的運作空間。如圖所示:

Android 程式間通信(IPC機制)精煉詳解
  • 核心空間:可以通路受保護的記憶體空間,有通路底層硬體裝置的所有權限;
  • 使用者空間:上層應用程式和Native層的運作空間,使用者空間沒法直接訪
  • 核心空間,需要系統調用才可以通路核心空間。

不同程序之間,使用者空間是不共享,但是核心空間是可以共享。

(3)定義多程序

預設情況下,啟動一個APP,僅僅啟動了一個程序,該程序名為包名,那如何定義多程序呢? Android 提供了一種方式,就是在 AndroidManifest 檔案中可以通過 “android:process” 來指定程序:

  • 1)不指定 process: 預設的程序,程序名為包名;
  • 2)指定 process,但以":"開頭: 該程序為目前APP的私有程序,不允許其他APP通路
  • 3)指定process,但以小寫字母開頭的字元串: 該程序為全局程序 ,其他應用可設定相同的shareUID來共享該程序

(4)為什麼要引入多程序?

為什麼一個 Android 應用要引入多程序?多程序有哪些應用場景呢?

通常在下面兩種情況下需要引入多程序:

  • 由于 Android 系統會限制每個應用的最大記憶體,是以如果一個應用需要更多可用的記憶體時,就需要引入多程序,讓某些子產品運作在另外的程序中,擷取更多的記憶體;
  • 由于不同的應用運作在不同的程序中,但是如果兩個不同的應用之間需要進行資料通信

(5)跨程序通信

既然在 Android 中引入了多程序,而對于程序的使用者空間不共享,那麼多程序之間怎麼通信呢?

這種多程序通信又稱為IPC(Inter Process Communication)

對于IPC,并不是Android系統特有的,在Linux系統中就存在的跨程序通信,在Linux系統中常見的IPC方式有:

  • 1)管道Pipe: 在記憶體中建立一個共享檔案,利用共享檔案傳遞資訊。該共享檔案并不是檔案系統,隻存在于記憶體中;隻能在一個方向上流動
  • 2)信号Signal: 異步通信。信号在使用者空間和核心空間之間互動,核心可利用信号來通知使用者空間的程序發生哪些系統事件。不适用于信号交換,适用于過程中斷控制;
  • 3)信号量Semaphore: 控制多個程序對共享資源的通路。主要是程序間以及同一程序不同線程之間的同步手段;
  • 4)消息隊列 Message Queue: 存放在記憶體中并由消息對了辨別符辨別,允許一個或多個程序對它進行讀寫消息。資訊會複制兩次,不适用于頻繁或資訊量大的通信
  • 5)共享記憶體Shared Memory: 直接讀寫核心的一塊記憶體空間。不需要進行資料拷貝
  • 6)套接字Socket: 不同機器之間程序間通信。

而在 Android 中,場景的 IPC 方式有:

  • 1)Bundle: 實作了Parcelable接口,常用于Activity、Service、BroadcastReceive之間的通信
  • 2)檔案共享: 常用于無并發,交換實時性不高的資料
  • 3)Messenger: 低并發的一對多即時通信。串行的方式處理Client發來的消息,隻能傳輸資料,不能方法調用(RPC)
  • 4)ContentProvider: 存儲和擷取資料,不同程式之間共享資料。一對多的資料共享
  • 5)AIDL
  • 6)Socket: 網絡資料交換

除去 Socket,其他的都是基于 Binder 機制實作的

(6)多程序帶來的問題

在程序結構中也提到了使用者空間是不共享的,并且每個程序都是對應單獨的系統堆棧區、靜态區等,那麼多程序也引入了一些問題:

  • 每個程序都是保持自己單獨的靜态成員變量和單例;
  • 每個程序都是單獨的程序鎖;
  • SharedPreferences可靠性下降,不支援并發寫;
  • 對于單個APP的多程序,就會建立多個Application,每個程序都會擁有己的Application對象。
題外話: 最後的這個資訊讓我想起之前看 web 開發相關的一些資訊:Tomcat 也是運作在 Linux 系統中,在部署 web 應用的時候,可以把一個 web 應用部署到多個 Tomcat 伺服器上,那麼每個 Tomcat 伺服器都會給該 web 應用配置設定一個 ServletContext

這篇文章,其實不難;主要是将 Android 中的跨程序通信以及開發當中經常用到的一些知識點,總結了一下

想要往向更深入學習難免需要尋找很多的學習資料輔助,我在這裡推薦網上整合的一套 《 Android 跨程序通信學習手冊》;有需要的小夥伴:可在評論區下方留言,或者 私信發送 "IPC進階" 即可 直達領取;鑒于出自大佬之手,可以幫助到大家,能夠少走些彎路

手冊包含如下技術點:

Android IPC學習

bionic學習

framework層c++篇

framework層Java篇

IPC binder 相關結構體

IPC binder的三大接口

IPC binder跨程序通信補充

IPC binder架構

IPC binder驅動

IPC binder總結

IPC binder總結

jni學習

linux學習

misc

跨程序通信IPC之AID

文檔内容展示如下:

IPC 跨程序 之 Framework 層 C++ 篇

  • ServiceManager 的啟動
  • ServiceManager 的核心服務
  • ServiceManager 的獲得
  • 注冊服務
  • 獲得服務
Android 程式間通信(IPC機制)精煉詳解

Binder 之 Framework 層 Java 篇

  • startReg()函數
  • register_android_os_Binder()函數
  • getIServiceManager()方法
  • addService()方法詳解
  • ServiceManager.getService()方法
Android 程式間通信(IPC機制)精煉詳解

IPC 之 Binder 的補充

  • Binder 中的線程池
  • Binder 的權限
  • Binder 的死亡通知機制
Android 程式間通信(IPC機制)精煉詳解

IPC 之 Binder 總結

  • Android 為什麼選用 Binder 作為最重要的 IPC 機制
  • Binder 中相關的類簡述
  • Binder 機制概述
  • Binder 通信概述
  • Binder 協定
  • Binder 架構
Android 程式間通信(IPC機制)精煉詳解
篇幅原因,就不在這裡為大家贅述了,有需要的小夥伴:可在評論區下方留言,或者 私信發送 "IPC進階" 即可 直達領取這份 《Android 跨程序通信學習手冊》
Android 程式間通信(IPC機制)精煉詳解

最後大家如果覺得手冊内容有用的話,可以點贊分享一下哦~

繼續閱讀