理解Android系統(tǒng)Binder機制
一、Binder機制概述
在Android開發(fā)中,很多時候我們需要用到進程間通信,所謂進程間通信,實現(xiàn)進程間通信的機制有很多種,比如說socket、pipe等,Android中進程間通信的方式主要有三種:
1.標準Linux Kernel IPC 接口;
2.標準D-BUS接口;
3.Binder接口。
其中,Binder機制是使用最且最被認可的,因為Binder機制有以下優(yōu)點:
1.相對于其它IPC機制,Binder機制更加簡潔和快速;
2.消耗的內(nèi)存相對更少;
3.傳統(tǒng)的IPC機制可能會增加進程的開銷,以及出現(xiàn)進程過載和安全漏洞,Binder機制則有效避免和解決了這些問題。
Binder機制是Android系統(tǒng)的核心機制,幾乎貫穿于整個Android系統(tǒng),Android系統(tǒng)基本上可以看作是一個基于binder通信機制的C/S架構(gòu),Binder就像網(wǎng)絡(luò),把Android系統(tǒng)的各個部分連接到了一起。利用Binder機制,可以實現(xiàn)以下功能:
1.用驅(qū)動程序來推進進程間通信;
2.通過共享內(nèi)存來提高性能;
3.為進程請求分配每個進程的線程池;
4.針對系統(tǒng)中的對象引入了引用計數(shù)和跨進程的對象引用映射;
5.進程間同步調(diào)用。
二、Binder機制的工作流程
1.客戶端獲取服務端的帶來對象(proxy)。我們需要明確的是客戶端進程并不能直接操作服務端中的方法,如果要操作服務端中的方法,那么有一個可行的解決方法就是在客戶端建立一個服務端進程的代理對象,這個代理對象具備和服務端進程一樣的功能,要訪問服務端進程中的某個方法,只需要訪問代理對象中對應的方法即可;
2.客戶端通過調(diào)用代理對象向服務端發(fā)送請求。
3.代理對象將用戶請求通過Binder驅(qū)動發(fā)送到服務器進程;
4.服務端進程處理客戶端發(fā)過來的請求,處理完之后通過Binder驅(qū)動返回處理結(jié)果給客戶端的服務端代理對象;
5.代理對象將請求結(jié)果進一步返回給客戶端進程。
通過以上5個步驟,就完成了一次Binder通信。
三、Binder機制的組成
Binder機制由三部分組成,即:
1.Client;
2.Server;
3.ServiceManager。
三部分組件之間的關(guān)系:
1.Client、Server、ServiceManager均在用戶空間中實現(xiàn),而Binder驅(qū)動程序則是在內(nèi)核空間中實現(xiàn)的;
2.在Binder通信中,Server進程先注冊一些Service到ServiceManager中,ServiceManager負責管理這些Service并向Client提供相關(guān)的接口;
3.Client進程要和某一個具體的Service通信,必須先從ServiceManager中獲取該Service的相關(guān)信息,Client根據(jù)得到的Service信息與Service所在的Server進程建立通信,之后Clent就可以與Service進行交互了;
4.Binder驅(qū)動程序提供設(shè)備文件/dev/binder與用戶空間進行交互,Client、Server和ServiceManager通過open和ioctl文件操作函數(shù)與Binder驅(qū)動程序進行通信;
5.Client、Server、ServiceManager三者之間的交互都是基于Binder通信的,所以通過任意兩者這件的關(guān)系,都可以解釋Binder的機制。
四、Binder驅(qū)動的實現(xiàn)簡介
1.Binder采用了AIDL來描述進程間的接口;
2.Binder是一個特殊的字符型設(shè)備,設(shè)備節(jié)點為dev/binder。
3.Binder驅(qū)動程序由以下兩個文件實現(xiàn):
①kernel/drivers/staging/binder.h
?、趉ernel/drivers/staging/binder.c
4.在Binder驅(qū)動的實現(xiàn)過程中,以下函數(shù)起著關(guān)鍵作用:
?、偈褂胋inder_ioctl()函數(shù)與用戶空間交換數(shù)據(jù);
?、贐INDER_WRITE_READ用來讀寫數(shù)據(jù),數(shù)據(jù)包中的cmd域用于區(qū)分不同的請求;
?、凼褂胋inder_thread_write()函數(shù)來發(fā)送請求或返回結(jié)果,在binder_thread_write()函數(shù)中,通過調(diào)用binder_transaction()函數(shù)來轉(zhuǎn)發(fā)請求并返回結(jié)果.當收到請求時,binder_transaction()函數(shù)會通過對象的handle找到對象所在的進程,如果handle結(jié)果為空,則認為此對象是context_mgr,然后把請求發(fā)給context_mgr所在的進程,并將請求中所有的Binder對象放到RB樹中,最后把請求放到目標進程的隊列中以等待目標進程的讀取。;
?、苁褂胋inder_thread_read()函數(shù)來讀取結(jié)果;
?、菰诤瘮?shù)binder_parse()中實現(xiàn)數(shù)據(jù)解析工作?! ?/p>
五、Binder驅(qū)動程序中的數(shù)據(jù)結(jié)構(gòu)
1.binder_work。binder_work表示在binder驅(qū)動中進程要處理的工作項。
2.binder_node。binder_node用于定義Binder實體對象。Android系統(tǒng)中每一個Srevice組件在Binder驅(qū)動程序中都對應一個Binder實體對象。驅(qū)動中的Binder實體也叫做“節(jié)點”,你屬于提供實體的進程;
3.binder_ref。binder_ref用于描述一個Binder引用對象。Android系統(tǒng)中每一個Client組件在Binder驅(qū)動程序中都對應一個Binder引用對象;
4.binder_ref_death。binder_ref_death是一個通知結(jié)構(gòu)體。只要某進程訂閱了某binder引用對應實體的死亡通知,那么binder驅(qū)動就會為該binder引用建立一個binder_ref_death通知結(jié)構(gòu)體,將其保存在當前進程的對應binder引用結(jié)構(gòu)體的death域中,即Binder引用對象將死亡通知注冊到Binder驅(qū)動程序中。這里涉及到Binder的死亡通知機制,Binder的死亡通知機制具體指:如果Binder實體對象意外死亡,那么將會導致改Binder實體對象的引用變得無效,因而就需要在Binder實體對象死亡的時候通知到所有引用它的代理對象,從而在一定程度上預防和解決Binder飲用對象無效的問題;
5.binder_buffer。Binder_Buffer用于描述一個內(nèi)核緩沖區(qū),能夠在進程之間傳輸數(shù)據(jù);
6.binder_proc。binder_proc表示正在使用Binder進程通信機制的進程,能夠保存調(diào)用Binder的各個進程或線程的信息,如線程ID、進程ID、Binder狀態(tài)信息等;
7.binder_thread。binder_thread用于存儲每一個單獨的線程的信息,表示Binder線程池中的一個線程;
8.binder_transaction。binder_transaction用于中轉(zhuǎn)請求和返回結(jié)果,并保存接收和要發(fā)送的進程信息;
9.binder_write_read。binder_write_read表示在進程之間的通信過程中傳輸?shù)臄?shù)據(jù),數(shù)據(jù)包中有一個cmd域用于區(qū)分不同的請求;
10.BinderDriverCommandProtocol。結(jié)構(gòu)體binder_write_read包含的命令在BinderDriverCommandProtocol中定義;
11.BinderDriverReturnProtocol。BinderDriverReturnProtocol中定義了讀操作命令協(xié)議;
12.binder_ptr_cookie。binder_ptr_cookie表示一個Binder實體對象或Service組件的死亡接收通知;
13.binder_transaction_data。binder_transaction_data表示在通信過程中傳遞的數(shù)據(jù);
14.flat_binder_object。flat_binder_object表示Binder對象。Android系統(tǒng)中,在進程之間傳遞的數(shù)據(jù)稱為Binder對象。
六、Binder的詳細實現(xiàn)
1.設(shè)備初始化。Binder機制的設(shè)備初始化函數(shù)binder_init位于inder.c中,在進行設(shè)備初始化的時候binder_init會調(diào)用設(shè)備驅(qū)動接口函數(shù)device_initcall;
2.打開設(shè)備文件。Binder機制,函數(shù)binder_open用于打開Binder設(shè)備文件/dev/binder。Android系統(tǒng)中,驅(qū)動程序的任何一個進程及線程都可以打開一個Binder設(shè)備;與binder_open函數(shù)功能相反的是binder_release函數(shù),用于釋放打開的空間以及操作過程中分配的空間;
3.實現(xiàn)內(nèi)存映射。當打開Binder設(shè)備文件/dev/binder之后,需要調(diào)用函數(shù)mmap()把設(shè)備內(nèi)存映射到用戶進程地址空間中,這樣就可以像操作用戶內(nèi)存那樣操作設(shè)備內(nèi)存。在Binder設(shè)備中,對內(nèi)存的映射操作是有限制的,如Binder不能映射具有寫權(quán)限的內(nèi)存區(qū)域,最大能映射4MB的內(nèi)存區(qū)域等;
4.釋放物理頁面。Binder機制中,函數(shù)binder_insert_free_buffer()用于將進程中的Buffer插入進程信息中,即將一個空閑內(nèi)核緩沖區(qū)加入進程中的空閑內(nèi)核緩沖區(qū)的紅黑樹中;
5.處理內(nèi)核緩沖區(qū):
?、?binder_alloc_buf()用于分配內(nèi)核緩沖區(qū);
?、赽inder_insert_allocated_buffer()用于將分配的內(nèi)核緩沖區(qū)添加到目標進程的已分配物理頁面的內(nèi)核緩沖區(qū)紅黑樹中;
?、踒inder_free_buf()用于釋放內(nèi)核緩沖區(qū)的操作;
?、?buffer_start_page()和*buffer_end_page()用于計算結(jié)構(gòu)體binder_buffer所占用的虛擬頁面的地址;
?、輇inder_delete_free_buffer()用于刪除結(jié)構(gòu)體binder_buffer;
?、?binder_buffer_lookup()根據(jù)一個用戶空間地址查詢一個內(nèi)核緩沖區(qū)。
七、Binder封裝庫
Android源碼中,各個層次都有Binder的相關(guān)實現(xiàn),其中主要由本地原生代碼實現(xiàn),其它層次的Binder實現(xiàn)都是調(diào)用原生Binder庫來實現(xiàn)的。
Binder的各層次實現(xiàn)為:
1.Binder驅(qū)動部分。實現(xiàn)功能如下:
?、俳M織Binder的服務及誒到哪;
②調(diào)用Binder相關(guān)的處理線程;
?、弁瓿蓪嶋H的Binder傳輸。
2.Binder Adapter層。Binder Adapter層是對Binder驅(qū)動的封裝,主要功能是操作Binder驅(qū)動,因而應用程序無須直接和Binder驅(qū)動程序關(guān)聯(lián)。關(guān)聯(lián)文件包括IPCThreadState.cpp、ProcessState.cpp和Parcel.cpp中的一些內(nèi)容。Binder核心庫是Binder框架的核心實現(xiàn),主要包括IBinder、Binder(服務端)和BpBinder(客戶端)。
3.頂層。頂層binder框架和具體的客戶端。
以上就是關(guān)于Android系統(tǒng)Binder機制的全部內(nèi)容,希望對大家學習Android軟件編程有所幫助。
- Android通過繼承Binder類實現(xiàn)多進程通信
- Android學習之介紹Binder的簡單使用
- Android系統(tǒng)進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
- Android系統(tǒng)進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析
- Android系統(tǒng)進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析
- Android系統(tǒng)進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
- 淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路
- Android深入淺出之Binder機制
- Android進程間通信(IPC)機制Binder簡要介紹
- Android4.1中BinderService用法實例分析
- android IPC之binder通信機制
- Android中Binder詳細學習心得
相關(guān)文章
Android自定義控件之創(chuàng)建可復用的組合控件
這篇文章主要為大家詳細介紹了Android自定義控件之創(chuàng)建可復用的組合控件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12
Android如何判斷一個點在不在多邊形區(qū)域內(nèi)
這篇文章主要為大家詳細介紹了Android判斷一個點在不在多邊形區(qū)域內(nèi)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
flutter實現(xiàn)掃碼槍獲取數(shù)據(jù)源禁止系統(tǒng)鍵盤彈窗示例詳解
這篇文章主要為大家介紹了flutter實現(xiàn)掃碼槍獲取數(shù)據(jù)源禁止系統(tǒng)鍵盤彈窗示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01
android 調(diào)用系統(tǒng)的照相機和圖庫實例詳解
android手機有自帶的照相機和圖庫,我們做的項目中有時用到上傳圖片到服務器,今天做了一個項目用到這個功能,所以把我的代碼記錄下來和大家分享,有需求的朋友可以參考下2012-12-12
分析Android 11.0Settings源碼之主界面加載
這篇文章主要介紹了分析Android 11.0Settings源碼之主界面加載,對Android源碼感興趣的同學,可以著重看一下2021-04-04

