引言
? Android的IPC采用的C/S架構(gòu)挺智,這樣的話各個(gè)進(jìn)程可以去實(shí)現(xiàn)自己的功能祷愉,若需要使用自己未實(shí)現(xiàn)但其他進(jìn)程實(shí)現(xiàn)了的功能,則可以很方便的作為調(diào)用客戶端去訪問實(shí)現(xiàn)該功能的服務(wù)端從而使用其對(duì)應(yīng)功能赦颇。例如二鳄,要使用視頻,音頻等功能只需作為客戶端去訪問實(shí)現(xiàn)視頻沐扳,音頻功能接口的進(jìn)程服務(wù)端泥从,然后調(diào)用服務(wù)端的對(duì)應(yīng)接口方法即可句占。
為什么是Binder
? 由于Android是基于Linux系統(tǒng)開發(fā)的操作系統(tǒng)沪摄,所以Linux的固有的IPC方式,在Android上也是適用的纱烘,但要達(dá)到上述的C/S架構(gòu)模式杨拐,只有Socket套接字才行,但是Socket的傳輸性能較差擂啥,通常用于低頻的IPC通信哄陶,所以在Android上實(shí)現(xiàn)了一套Binder機(jī)制用于在Android上進(jìn)行IPC通信。
? 那么Binder為何被選中作為Android的IPC機(jī)制呢哺壶?上述說到屋吨,Linux原本支持的IPC中只有Socket采用的是C/S架構(gòu),但性能不好山宾,這當(dāng)然是原因之一至扰。說到性能的話,我們從傳輸性能资锰,安全性能方面說起敢课。
傳輸性能
? 由于Linux對(duì)于進(jìn)程有著沙盒機(jī)制直秆,即每個(gè)進(jìn)程被“沙盒”封裝起來圾结,進(jìn)程間彼此獨(dú)立培他,這樣當(dāng)一個(gè)進(jìn)程崩潰的話舀凛,其他進(jìn)程仍可以正常運(yùn)行,系統(tǒng)仍能正常運(yùn)行懊烤。但有時(shí)需要進(jìn)程間傳遞數(shù)據(jù)腌紧,進(jìn)行通信壁肋,那么就提供了一系列的IPC方式浸遗,如:管道跛锌,共享內(nèi)存髓帽,消息隊(duì)列郑藏,信號(hào)量和Socket译秦。
? 但由于進(jìn)程間通信都需要經(jīng)過Linux內(nèi)核们拙,在內(nèi)核中直接進(jìn)行通信,所以就涉及到進(jìn)程將數(shù)據(jù)拷貝到Linux內(nèi)核的操作装盯。除共享內(nèi)存外埂奈,其余方式都至少需要拷貝2次(進(jìn)程用戶空間拷貝至內(nèi)核空間定躏,再從內(nèi)核空間拷貝至目標(biāo)進(jìn)程的用戶空間账磺,共享內(nèi)存無需拷貝)痊远。詳情可見下表:
IPC方式 | 拷貝次數(shù) |
---|---|
共享內(nèi)存 | 0 |
Binder | 1 |
管道/消息隊(duì)列/信號(hào)量/Socket | 2 |
為什么Binder只需一次呢?因?yàn)锽inder在Linux內(nèi)核空間獨(dú)立出了一塊區(qū)域碧聪,可直接讀取服務(wù)端數(shù)據(jù)冒版,只需要客戶端將數(shù)據(jù)拷貝至此處即可逞姿。
? 由上可看到辞嗡,傳輸次數(shù)減少了哼凯,帶來的資源消耗就少了断部,從而加大了傳輸性能达址。
簡述之:Binder相對(duì)而言減少了數(shù)據(jù)拷貝次數(shù)達(dá)到提高傳輸性能的目的蔑祟。
安全性能
? 那么,為什么Binder更具安全性呢?縱觀其他的IPC方式径簿,我們無法得知進(jìn)行通信的端口是否合法(滿足要求)罢屈,即無論是誰,只要搭上了這條鏈路篇亭,即可進(jìn)行數(shù)據(jù)交換缠捌。然而,Binder對(duì)每個(gè)進(jìn)程都分配了UID/PID译蒂,當(dāng)通過Binder進(jìn)行IPC時(shí)曼月,系統(tǒng)會(huì)去核對(duì)UID/PID是否合法,只要系統(tǒng)認(rèn)為合法的PID柔昼,才能搭上Binder的車哑芹。如此,在IPC上增加一道關(guān)卡捕透,保障IPC通信安全绩衷,所以相對(duì)其他IPC方式更具安全性。
簡述之:Binder通過UID/PID來保證通信雙方的合法性激率,進(jìn)而達(dá)到IPC間消息傳輸?shù)陌踩浴?/strong>
Binder通信模型
? 說到通信模型咳燕,主要是通信的組成成員和其架構(gòu)模式。架構(gòu)上文已說到乒躺,采用的C/S架構(gòu)招盲,那么這里主要說說組成成員。
? Binder的組成成員共有四員大將:Server嘉冒,Client曹货,ServiceManager和Binder驅(qū)動(dòng)。
Binder驅(qū)動(dòng)
? Binder驅(qū)動(dòng)讳推,雖然叫驅(qū)動(dòng)顶籽,但并不是真正的硬件驅(qū)動(dòng)钙态,而只是實(shí)現(xiàn)了驅(qū)動(dòng)效果的一套代碼而已闯冷。并且它運(yùn)行在內(nèi)核區(qū)包个,因此它是真正達(dá)到IPC效果的地方历葛。
? 上述說到缤剧,它實(shí)現(xiàn)了驅(qū)動(dòng)效果吹艇,即實(shí)現(xiàn)驅(qū)動(dòng)的一些方法如epoll()什么的夹攒。使用起來和真正的操作驅(qū)動(dòng)并未差別带欢。
Server和Server中的Binder
? Server作為Binder架構(gòu)中服務(wù)端洒忧,是提供功能的一端蝴韭,通過Binder暴露功能調(diào)用接口給外部,任何進(jìn)程拿到其Binder熙侍,即可通過Binder調(diào)用功能接口去調(diào)用功能榄鉴。在Server中履磨,Binder是以實(shí)體存在。外部或得的是Binder實(shí)體的引用庆尘,可以說指針或句柄蹬耘,都是一個(gè)意思,因?yàn)槭茿ndroid開發(fā)者减余,說引用的話比較好理解综苔。
Client和Client中的Binder
? Client作為Binder架構(gòu)中的客戶端,是調(diào)用功能的一端位岔,其拿到的Binder并非是Binder實(shí)體如筛,而是指向該Binder實(shí)體的引用。
ServiceManager和ServiceManager中的Binder
? ServiceManager是類似于DNS的存在抒抬,存儲(chǔ)了Binder名稱和Binder實(shí)體的對(duì)應(yīng)關(guān)系表杨刨。類似于域名和IP的對(duì)應(yīng)關(guān)系。當(dāng)有新的Service時(shí)擦剑,需要向ServiceManager進(jìn)行注冊(cè)妖胀,以便其他客戶端想調(diào)用其功能時(shí)可以找到該Binder實(shí)體的引用。那么這必然是一次IPC過程惠勒,那么在還未搭建IPC橋梁的時(shí)候進(jìn)行IPC必然是自相矛盾的赚抡,所以系統(tǒng)將ServiceManager的Binder實(shí)體的Binder引用干脆暴露出來,讓所有進(jìn)程都知道其Binder引用是什么纠屋,這樣就可以直接進(jìn)行注冊(cè)涂臣。當(dāng)新的Service向ServiceManager注冊(cè)后,客戶端調(diào)用時(shí)會(huì)在請(qǐng)求體中包含請(qǐng)求的Binder名稱售担,ServiceManager會(huì)根據(jù)名稱找到對(duì)應(yīng)Binder的引用赁遗,然后告訴客戶端,這樣客戶端就拿到服務(wù)端的Binder引用族铆,然后就可以根據(jù)該引用去調(diào)用服務(wù)端的相關(guān)接口方法岩四。
特別鳴謝
https://blog.csdn.net/universus/article/details/6211589 -------- Android Bander設(shè)計(jì)與實(shí)現(xiàn) - 設(shè)計(jì)篇