#Binder機制
---
首先Binder是Android系統進程間通信(IPC)方式之一。
Binder使用Client-Server通信方式。Binder框架定義了四個角色:Server,Client,ServiceManager以及Binder驅動。其中Server,Client,ServiceManager運行于用戶空間,驅動運行于內核空間。Binder驅動程序提供設備文件/dev/binder與用戶空間交互,Client、Server和Service Manager通過open和ioctl文件操作函數與Binder驅動程序進行通信。
Server創建了Binder實體,為其取一個字符形式,可讀易記的名字,將這個Binder連同名字以數據包的形式通過Binder驅動發送給ServiceManager,通知ServiceManager注冊一個名字為XX的Binder,它位于Server中。驅動為這個穿過進程邊界的Binder創建位于內核中的實體結點以及ServiceManager對實體的引用,將名字以及新建的引用打包給ServiceManager。ServiceManager收數據包后,從中取出名字和引用填入一張查找表中。但是一個Server若向ServiceManager注冊自己Binder就必須通過0這個引用和ServiceManager的Binder通信。Server向ServiceManager注冊了Binder實體及其名字后,Client就可以通過名字獲得該Binder的引用了。Clent也利用保留的0號引用向ServiceManager請求訪問某個Binder:我申請名字叫XX的Binder的引用。ServiceManager收到這個連接請求,從請求數據包里獲得Binder的名字,在查找表里找到該名字對應的條目,從條目中取出Binder引用,將該引用作為回復發送給發起請求的Client。
當然,不是所有的Binder都需要注冊給ServiceManager廣而告之的。Server端可以通過已經建立的Binder連接將創建的Binder實體傳給Client,當然這條已經建立的Binder連接必須是通過實名Binder實現。由于這個Binder沒有向ServiceManager注冊名字,所以是匿名Binder。Client將會收到這個匿名Binder的引用,通過這個引用向位于Server中的實體發送請求。匿名Binder為通信雙方建立一條私密通道,只要Server沒有把匿名Binder發給別的進程,別的進程就無法通過窮舉或猜測等任何方式獲得該Binder的引用,向該Binder發送請求。
---
###為什么Binder只進行了一次數據拷貝?
Linux內核實際上沒有從一個用戶空間到另一個用戶空間直接拷貝的函數,需要先用copy_from_user()拷貝到內核空間,再用copy_to_user()拷貝到另一個用戶空間。為了實現用戶空間到用戶空間的拷貝,mmap()分配的內存除了映射進了接收方進程里,還映射進了內核空間。所以調用copy_from_user()將數據拷貝進內核空間也相當于拷貝進了接收方的用戶空間,這就是Binder只需一次拷貝的‘秘密’。
最底層的是Android的ashmen(Anonymous shared memory)機制,它負責輔助實現內存的分配,以及跨進程所需要的內存共享。AIDL(android interface definition language)對Binder的使用進行了封裝,可以讓開發者方便的進行方法的遠程調用,后面會詳細介紹。Intent是最高一層的抽象,方便開發者進行常用的跨進程調用。
從英文字面上意思看,Binder具有粘結劑的意思那么它是把什么東西粘接在一起呢?在Android系統的Binder機制中,由一系統組件組成,分別是Client、Server、Service Manager和Binder驅動,其中Client、Server、Service Manager運行在用戶空間,Binder驅動程序運行內核空間。Binder就是一種把這四個組件粘合在一起的粘連劑了,其中,核心組件便是Binder驅動程序了,ServiceManager提供了輔助管理的功能,Client和Server正是Binder驅動和ServiceManager提供的基礎設施上,進行Client-Server之間的通信。
1. Client、Server和ServiceManager實現在用戶空間中,Binder驅動實現在內核空間中
2. Binder驅動程序和ServiceManager在Android平臺中已經實現,開發者只需要在用戶空間實現自己的Client和Server
3. Binder驅動程序提供設備文件/dev/binder與用戶空間交互,Client、Server和ServiceManager通過open和ioctl文件操作函數與Binder驅動程序進行通信
4. Client和Server之間的進程間通信通過Binder驅動程序間接實現
5. ServiceManager是一個守護進程,用來管理Server,并向Client提供查詢Server接口的能力
服務器端:一個Binder服務器就是一個Binder類的對象。當創建一個Binder對象后,內部就會開啟一個線程,這個線程用戶接收binder驅動發送的消息,收到消息后,會執行相關的服務代碼。
Binder驅動:當服務端成功創建一個Binder對象后,Binder驅動也會相應創建一個mRemote對象,該對象的類型也是Binder類,客戶就可以借助這個mRemote對象來訪問遠程服務。
客戶端:客戶端要想訪問Binder的遠程服務,就必須獲取遠程服務的Binder對象在binder驅動層對應的binder驅動層對應的mRemote引用。當獲取到mRemote對象的引用后,就可以調用相應Binde對象的服務了。
在這里我們可以看到,客戶是通過Binder驅動來調用服務端的相關服務。首先,在服務端創建一個Binder對象,接著客戶端通過獲取Binder驅動中Binder對象的引用來調用服務端的服務。在Binder機制中正是借著Binder驅動將不同進程間的組件bind(粘連)在一起,實現通信。
mmap將一個文件或者其他對象映射進內存。文件被映射進內存。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最后一個頁不被使用的空間將會凋零。munmap執行相反的操作,刪除特定地址區域的對象映射。
當使用mmap映射文件到進程后,就可以直接操作這段虛擬地址進行文件的讀寫等操作,不必再調用read,write等系統調用。但需注意,直接對該段內存寫時不會寫入超過當前文件大小的內容。
使用共享內存通信的一個顯而易見的好處是效率高,因為進程可以直接讀寫內存,而不需要任何數據的拷貝。對于像管道和消息隊列等通信方式,則需要在內核和用戶空間進行四次的數據拷貝,而共享內存則只拷貝兩次內存數據:一次從輸入文件到共享內存區,另一次從共享內存到輸出文件。實際上,進程之間在共享內存時,并不總是讀寫少量數據后就解除映射,有新的通信時,再重新建立共享內存區域,而是保持共享區域,直到通信完成為止,這樣,數據內容一直保存在共享內存中,并沒有寫回文件。共享內存中的內容往往是在解除內存映射時才寫回文件的。因此,采用共享內存的通信方式效率是非常高的。
aidl主要就幫助了我們完成了包裝數據和解包的過程,并調用了transact過程,而用來傳遞的數據包我們就稱為parcel
AIDL:xxx.aidl -> xxx.java ,注冊service
1. 用aidl定義需要被調用方法接口
2. 實現這些方法
3. 調用這些方法
- JavaSE(Java基礎)
- Java基礎知識
- Java中的內存泄漏
- String源碼分析
- Java集合結構
- ArrayList源碼剖析
- HashMap源碼剖析
- Hashtable簡介
- Vector源碼剖析
- LinkedHashMap簡介
- LinkedList簡介
- JVM(Java虛擬機)
- JVM基礎知識
- JVM類加載機制
- Java內存區域與內存溢出
- 垃圾回收算法
- Java并發(JavaConcurrent)
- Java并發基礎知識
- 生產者和消費者問題
- Thread和Runnable實現多線程的區別
- 線程中斷
- 守護線程與阻塞線程的情況
- Synchronized
- 多線程環境中安全使用集合API
- 實現內存可見的兩種方法比較:加鎖和volatile變量
- 死鎖
- 可重入內置鎖
- 使用wait/notify/notifyAll實現線程間通信
- NIO
- 數據結構(DataStructure)
- 數組
- 棧和隊列
- Algorithm(算法)
- 排序
- 選擇排序
- 冒泡排序
- 快速排序
- 歸并排序
- 查找
- 順序查找
- 折半查找
- Network(網絡)
- TCP/UDP
- HTTP
- Socket
- OperatingSystem(操作系統)
- Linux系統的IPC
- android中常用設計模式
- 面向對象六大原則
- 單例模式
- Builder模式
- 原型模式
- 簡單工廠
- 策略模式
- 責任鏈模式
- 觀察者模式
- 代理模式
- 適配器模式
- 外觀模式
- Android(安卓面試點)
- Android基礎知識
- Android內存泄漏總結
- Handler內存泄漏分析及解決
- Android性能優化
- ListView詳解
- RecyclerView和ListView的異同
- AsyncTask源碼分析
- 插件化技術
- 自定義控件
- ANR問題
- Art和Dalvik的區別
- Android關于OOM的解決方案
- Fragment
- SurfaceView
- Android幾種進程
- APP啟動過程
- 圖片三級緩存
- Bitmap的分析與使用
- 熱修復的原理
- AIDL
- Binder機制
- Zygote和System進程的啟動過程
- Android中的MVC,MVP和MVVM
- MVP
- Android開機過程
- EventBus用法詳解
- 查漏補缺
- Git操作