Android的跨进程通信
Android系統的跨進程簡介
為什么不能直接跨進程通信?
為了安全考慮,應用之間的內存是無法互相訪問的,各自的數據都存在于自身的內存區域內。
如何跨進程通信?
要想跨進程通信,就要找到一個大家都能訪問的地方,例如硬盤上的文件,多個進程都可以讀寫該文件,通過對該文件進行讀寫約定好的數據,來達到通信的目的。
Android中的跨進程通信采用的是Binder機制,其底層原理是共享內存。
Binder機制
- Android中的跨進程通信采用的是Binder機制。
- Binder在linux層面屬于一個驅動,但是這個驅動不是去驅動一個硬件,而且驅動一小段內存。
- 不同的應用通過對一塊內存區域進行數據的讀、寫操作來達到通信的目的。
- 不同的應用在同一內存區域讀寫數據,為了告知其他應用如何理解寫入的數據,就需要一個說明文件,這就是AIDL。當兩個應用持有相同的AIDL文件,就能互相理解對方的的意圖,就能做出相應的回應,達到通信的目的。
系統服務
什么是系統服務?
由android系統提供的服務,以供應用程序調用,來操作手機。如果應用能直接操作手機,后果將不堪設想,為了安全性和統一性,所有手機操作都將由系統來完成,應用通過發送消息給系統服務來請求操作。系統服務就是系統開放給應用端的操作接口,類似于Web服務開放出來的接口。
我們通過context. getSystemService可以獲取到系統服務的代理對象,該代理對象內部有一個系統服務的遠程對象引用。代理對象和系統服務有相同的api接口,我們調用代理對象,代理對象會調用遠程對象,遠程對象通知系統服務,這樣操作起來就像直接訪問系統服務一樣輕松。
系統服務和應用端的通信機制
- 系統服務XxxService
是一個Binder類的子類,一旦創建后,就開啟一個線程死循環用來檢測某段內存是否有數據寫入
- Binder驅動
自身創建時,創建一個XxxRemote遠程對象,存放到Binder驅動中,XxxRemote遠程對象可以和XxxService系統服務通信
- 應用端
通過context. getSystemService()獲取XxxServiceProxy對象,該對象內部引用了XxxRemote對象, XxxServiceProxy和XxxService具有相同的API,我們調用XxxServiceProxy時,XxxServiceProxy就調用XxxRemote并等待XxxRemote返回。XxxRemote會往某段內存中寫入數據,寫完后就開始監視該內存區域,Binder驅動會把XxxRemote寫入的數據拷貝到XxxService監視著的內存區域,當XxxService一旦發現有數據,就讀取并進行處理,處理完畢后,就寫入該區域,這是Binder驅動又會把該數據拷貝到XxxRemote監視的內存區域,當XxxService發現內存區域有數據讀取該區域數據,并把內容返回給XxxServiceProxy。這樣就完成了一次進程間的通信。
所以一個系統服務會產生兩個Binder對象,一個是運行在系統中的系統服務本身,一個是存放到Binder驅動中的遠程對象。所不同的是系統服務Binder對象對開啟一個線程監聽消息,遠程對象不會,它是運行在調用者的線程中。
客戶端也可以不使用系統服務的遠程Binder對象,而是自己創建一個Binder對象,通過Binder驅動和系統服務進行關聯,這樣的好處客戶端可以隨時通知系統服務,系統服務也可以隨時通知客戶端,而不是像上面所說的系統服務只能被動的等著客戶端調用。
Binder間的通信機制
Binder對象都有各自的內存區域,當Binder1想要向Binder2發送數據時,就會把數據寫入自己的內存區域,然后通知Binder驅動,Binder驅動會把數據拷貝到Binder2的內存區域,然后通知Binder2進行讀取,Binder讀取完畢后,將把數據寫入binder2的內存區域,然后通知Binder驅動,Binder驅動將會把數據拷貝到Binder1的內存區域中。這樣就完成了一次通信。
如果Binder1是系統服務,Binder2是系統服務的遠程對象,這樣任何應用程序在獲取了Binder2的引用后,都可以和Binder1進行通信。但是缺點也很明顯,只能由應用端請求系統服務,系統服務不能主動去聯系應用端。WifiManagerService之類的就是采用這種方式。
還有一種方式是Binder1是系統服務,Binder2是應用端創建的Binder對象,他們兩者通過Binder驅動進行連接后,應用端可以主動調系統服務,系統服務也可以主動調用應用端。WindowManagerService就是采用的這種方式。
IPC
進程間通信或跨進程通信,是指兩個進程間進行數據交換的過程。
PRC:遠程過程調用
多進程
線程是CPU調度的最小單元,同時線程是一種有限的系統資源。而進程一般指一個執行單元,在PC和移動設備上指一個程序或者一個應用。一個進程可以包含多個線程,因此進程和線程是包含與被包含的關系。
- Intent
- Bundle
- 共享文件
- SharedPrefrence
- ContentProvider
- Messenger
- AIDL
- Binder
- Socket
Android中的多進程模式
- 一個應用中存在多個進程的情況
- 多個應用間的多進程
序列化
序列化,反序列化,持久化
Serializable
Java提供的一個序列化接口
序列化流
- ObjectInputStream
- ObjectOutputStream
Parcelable
Android提供的序列化接口
Binder
實現IBinder接口,是Android的一種跨進程通信方式,是客戶端和服務端進行通信的媒介
- IBinder
- Binder
- Stub
當客戶端發起遠程請求時,由于當前線程會被掛起直至服務端進程返回數據,所有一個遠程方法是很耗時的,那么不能在UI線程中發起此遠程請求;由于服務端的Binder運行在Binder的線程池中,所以Binder方法不管是否耗時都采用同步的方式去實現,因為它已經運行在一個線程中了
Binder死亡代理
- linkToDeath()
- unlinkToDeath()
共享文件
一個進程序列化對象到sd上的一個文件,另一個進程反序列化sd上的一文件
Messenger
底層實現是AIDL,一次處理一個請求,不用考慮線程同步的問題,主要作用是傳遞消息
AIDL
- 只支持方法,不支持靜態常量
- AIDL的包結構在服務端和客戶端要保持一致
RemoteCallbackList
- 實現了同步功能
總結
以上是生活随笔為你收集整理的Android的跨进程通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实现圆形图片
- 下一篇: Android应用程序模块:应用、任务、