做者:鴻洋java
對Binder學習感興趣的小夥伴能夠看看,但願能幫助到大家。api
爲何會有Binder通訊機制,爲何不能用linux中已有的進程框架呢?Google工程師到底是如何考量的?微信
這一切能夠經過一場戀愛來理解?架構
瞭解binder以前咱們看看原有Linux進程是如何通訊的吧!爲何須要在內存中拷貝兩次呢?框架
在瞭解Linux進程通訊前咱們先理解下 戀愛的故事吧!ide
故事:函數
男孩和女孩在某次旅遊一見傾心,而旅行結束的他們不得不返回各自的工做城市性能
那個時代尚未微信,因爲相隔在不一樣的城市。相思的他們只能經過郵局抒發彼此愛慕之情學習
若是男孩想要給女孩發送信封,須要向本地郵局 寄信。再有全國郵局轉發到 女孩所在的本地郵局
最後由本地郵局送到女孩手中
在進程中的角色:
男孩 稱爲進程A,工做城市A城,女孩稱爲進程B,工做城市B城
本地郵局稱爲用戶空間, 全國郵局稱爲內核空間
本地郵局是他們離的最近的地方。他們能夠接觸到本地郵局,能夠在郵局中直接收信和發信
轉換專業術語的圖
進程間,用戶空間的數據不可共享(本地郵局是男孩或女孩獨有),因此用戶空間至關於私有空間。
進程間,內核空間的數據可共享(全國郵局是全部人共有),因此內核空間 至關於公共空間。
進程間若是須要作到通訊,須要經過共享空間對數據轉換。轉換過程須要調用系統的api,這個過程稱爲系統調用。
問題來了:
男孩寫好信以後,發送信件給本地郵局 , 至關於一次拷貝 咱們把這個過程稱爲(copy_from_user)
女孩收到當地郵局通知,須要從本地郵局取信。至關於第二次拷貝,咱們把這個過程稱爲(copy_to_user)
這就是Linux已有進程間通訊方式。
兩次拷貝究竟性能怎麼樣,固然拷貝是很是耗性能的,而兩次拷貝能夠再優化優化。
那binder是怎麼作到一次拷貝的呢
後來在疫情結束後,這個女孩去了全國郵局依賴的快遞公司上班去了,全部的信封須要用快遞公司來處理,恰好這家快遞公司處理的是他們兩個城市的信件。
爲了方便收信封,竟然還有這操做
這就給女孩創造了便利,不用去本地郵局取信件
可是男孩仍是要發送信件。binder拷貝也是發生在男孩這個地方copyfromuser,女孩因爲在快遞公司上班,能夠隨意瀏覽男孩的信件。不須要再取信件了。也就減小了從本地郵局取快遞此次拷貝過程
思考: 你們還記不記得接收端怎麼寫的,對! 接收端必定必須是服務Service,接收端不能是其餘java對象。Service就是那個女孩。她必須在快遞公司上班才能減小一次拷貝。因此這個Service,在通訊前會註冊在ServiceManager中。而男孩能夠是任意對象,出如今任意地方。
Linux 已有的進程通訊,發送端和接收端能夠是任意對象。出如今任意類中。可是必須犧牲多拷貝一次
Android的Binder通訊,接收端不能是任意對象,只能是Service,這也節約了一次拷貝,犧牲了開發者的體驗
全國郵局 至關於內核空間的內存,全部的應用都與內核空間的內存發生頻繁的調用,在Binder中傳遞數據本質上是經過文件讀取來實現的
你們記不記得Linux系統 是文件操做系統,都是基於文件展開的。進程通訊中 File也能實現進程通訊
Binder機制中 在內存與文件中設計了一層映射關係。內核空間的內存是虛的,文件IO是實的。映射指的是內存與文件的映射,映射是經過mmap函數。
而mmap函數 須要依賴一個文件,這個文件叫作「binder」。對!他沒有後綴名,他就是一個文件。可是人們習慣性的把它稱爲binder驅動。
咱們再來看看實際的是如何映射的
全國郵局中的A城與B城的信件,至關於內核空間內存一部分虛擬內存區域。
A城與B城的快遞公司,至關於文件實體。實際信封是由快遞公司轉發。郵局與快遞公司的合做關係,能夠理解內存與文件造成了映射關係(mmap)
一旦有信件到達女孩的公司直接讀取出來,而不用去本地郵局取信件。
女孩怎麼在公司取出來呢?你們忘記了女孩在快遞公司上班呢,快遞公司會給員工佈置工做內容
女孩的工做內容是查看快遞接收站和發送站的信封
這樣你說能不能看到男友發過來的信件,還不用親自跑到本地郵局,那不是爽歪歪
綠色部分 是女孩進程,綠色內有兩個角色(女孩接觸到的 接收站和收發站)
這一套機制的實現基於 aidl文件編譯機制
在編譯時生成了一個繼承自Binder中的IInterface接口(女孩)。接口中有這樣一個內部類叫Stub(女孩工做接觸的接收站)和一個內部類叫Proxy(女孩工做接觸的發送站)
男孩信封到了,女孩直接在 快遞接收站查看男孩發過來的信封(Stub中的 onTransact方法)
女孩思戀男孩,給男孩發送信封(Proxy中的transact方法)
Stub與Proxy中全部的方法是native直接調用過來的。參數是直接從內核空間傳遞過來的,不須要發生拷貝。
若是女孩須要給男孩發送消息,也不用跑到本地郵局,直接在 快遞發送站,插入一個信封就行了(調用Proxy的transct方法)
減小一次拷貝發生在 服務端service。直接由nativie層 的Binder調起。不須要再次拷貝。
你們看完了 是否是對整個Binder機制有深入的認識呢?
若是還不是很理解的,能夠來看一下我搜集的一些關於Binder的詳細系統的學習資料和視頻從爲何會有Binder,到Binder原理,最後從Binder中mmap函數 能爲實際工做中解決儲存的問題。
從Binder的底層原理分析,讓Android開發者真正瞭解到Binder的通訊機制。從Linux進程通訊技術認知到爲何Android會選擇Binder做爲通訊方式,到Linux的進程原理,最後借鑑Binder中mmap函數打造優異的存儲框架。
有須要的小夥伴能夠私信我【Binder】我分享給你
但願在2020 資本寒冬和疫情的狀況下,你們都能抓住此次機會,在這段時間內努力提高本身技術,把本身變得更優秀,成爲不可替代的人。最後找到本身滿意的工做。
330頁Android進階核心筆記
精選Binder進階視頻
B站帳號:bili_84936792704 但願資料加視頻能夠提升你們學習的效率。