基于Android 6.0的源碼剖析焕毫, 本文詳細地講解defaultServiceManager流程
一. 概述
獲取Service Manager是通過defaultServiceManager()方法來完成堕战,當進程注冊服務(addService)或獲取服務(getService)的過程之前狡汉,都需要先調(diào)用defaultServiceManager()方法來獲取gDefaultServiceManager對象患民。對于gDefaultServiceManager對象懈凹,如果存在則直接返回泪蔫;如果不存在則創(chuàng)建該對象蹦狂,創(chuàng)建過程包括調(diào)用open()打開binder驅(qū)動設備磨总,利用mmap()映射內(nèi)核的地址空間嗦明。
1.1 流程圖
1.2 defaultServiceManager
[-> IServiceManager.cpp]
獲取ServiceManager對象采用單例模式,當gDefaultServiceManager存在蚪燕,則直接返回娶牌,否則創(chuàng)建一個新對象。 發(fā)現(xiàn)與一般的單例模式不太一樣馆纳,里面多了一層while循環(huán)诗良,這是google在2013年1月Todd Poynor提交的修改。當嘗試創(chuàng)建或獲取ServiceManager時鲁驶,ServiceManager可能尚未準備就緒鉴裹,這時通過sleep 1秒后,循環(huán)嘗試獲取直到成功灵嫌。gDefaultServiceManager的創(chuàng)建過程,可分解為以下3個步驟:
ProcessState::self():用于獲取ProcessState對象(也是單例模式)壹罚,每個進程有且只有一個ProcessState對象,存在則直接返回寿羞,不存在則創(chuàng)建猖凛,詳情見【小節(jié)二】;
getContextObject(): 用于獲取BpBinder對象,對于handle=0的BpBinder對象绪穆,存在則直接返回辨泳,不存在才創(chuàng)建,詳情見【小節(jié)三】;
interface_cast():用于獲取BpServiceManager對象玖院,詳情見【小節(jié)四】;
二. 獲取ProcessState對象
2.1 ProcessState::self
[-> ProcessState.cpp]
獲得ProcessState對象: 這也是單例模式菠红,從而保證每一個進程只有一個ProcessState對象。其中gProcess和gProcessMutex是保存在Static.cpp類的全局變量难菌。
2.2 初始化ProcessState
[-> ProcessState.cpp]
ProcessState的單例模式的惟一性试溯,因此一個進程只打開binder設備一次,其中ProcessState的成員變量mDriverFD記錄binder驅(qū)動的fd,用于訪問binder設備郊酒。
BINDER_VM_SIZE = (1*1024*1024) - (4096 *2), binder分配的默認內(nèi)存大小為1M-8k遇绞。
DEFAULT_MAX_BINDER_THREADS = 15,binder默認的最大可并發(fā)訪問的線程數(shù)為16燎窘。
2.3 open_driver
[-> ProcessState.cpp]
open_driver作用是打開/dev/binder設備摹闽,設定binder支持的最大線程數(shù)。關于binder驅(qū)動的相應方法褐健,見文章Binder Driver初探付鹿。
三. 獲取BpBinder對象
3.1 getContextObject
[-> ProcessState.cpp]
獲取handle=0的IBinder
3.2 getStrongProxyForHandle
[-> ProcessState.cpp]
當handle值所對應的IBinder不存在或弱引用無效時會創(chuàng)建BpBinder,否則直接獲取。 針對handle==0的特殊情況舵匾,通過PING_TRANSACTION來判斷是否準備就緒俊抵。如果在context manager還未生效前,一個BpBinder的本地引用就已經(jīng)被創(chuàng)建纽匙,那么驅(qū)動將無法提供context manager的引用务蝠。
3.3 lookupHandleLocked
[-> ProcessState.cpp]
根據(jù)handle值來查找對應的handle_entry,handle_entry是一個結構體拍谐,里面記錄IBinder和weakref_type兩個指針烛缔。當handle大于mHandleToObject的Vector長度時,則向該Vector中添加(handle+1-N)個handle_entry結構體轩拨,然后再返回handle向?qū)恢玫膆andle_entry結構體指針践瓷。
3.4 創(chuàng)建BpBinder
[-> BpBinder.cpp]
創(chuàng)建BpBinder對象中會將handle相對應Binder的弱引用增加1.
四. 獲取BpServiceManager
4.1 interface_cast
[-> IInterface.h]
這是一個模板函數(shù),可得出亡蓉,interface_cast()?等價于?IServiceManager::asInterface()晕翠。接下來,再來說說asInterface()函數(shù)的具體功能。
4.2 IServiceManager::asInterface
對于asInterface()函數(shù)砍濒,通過搜索代碼淋肾,你會發(fā)現(xiàn)根本找不到這個方法是在哪里定義這個函數(shù)的, 其實是通過模板函數(shù)來定義的,通過下面兩個代碼完成的:
接下來爸邢,再說說這兩行代碼分別完成的功能:
4.3 DECLARE_META_INTERFACE
[-> IInterface.h]
位于IServiceManager.h文件中,INTERFACE=ServiceManager展開即可得:
[-> IServiceManager.h]
該過程主要是聲明asInterface(),getInterfaceDescriptor()方法.
4.4 IMPLEMENT_META_INTERFACE
[-> IInterface.h]
位于IServiceManager.cpp文件中,INTERFACE=ServiceManager, NAME=”android.os.IServiceManager”展開即可得:
[-> IServiceManager.cpp]
不難發(fā)現(xiàn)樊卓,[小節(jié)4.2]的IServiceManager::asInterface()?等價于?new BpServiceManager()。在這里杠河,更確切地說應該是new BpServiceManager(BpBinder)碌尔。
4.5 BpServiceManager實例化
創(chuàng)建BpServiceManager對象的過程,會先初始化父類對象:
4.5.1 BpServiceManager初始化
[-> IServiceManager.cpp]
4.5.2 BpInterface初始化
[-> IInterface.h]
4.5.3 BpRefBase初始化
[-> Binder.cpp]
new BpServiceManager()券敌,在初始化過程中唾戚,比較重要工作的是類BpRefBase的mRemote指向new BpBinder(0),從而BpServiceManager能夠利用Binder進行通過通信待诅。
五. 總結
defaultServiceManager 等價于 new BpServiceManager(new BpBinder(0));
ProcessState::self()主要工作:
調(diào)用open()叹坦,打開/dev/binder驅(qū)動設備;
再利用mmap()卑雁,創(chuàng)建大小為1M-8K的內(nèi)存地址空間募书;
設定當前進程最大的最大并發(fā)Binder線程個數(shù)為16。
BpServiceManager巧妙將通信層與業(yè)務層邏輯合為一體序厉,
通過繼承接口IServiceManager實現(xiàn)了接口中的業(yè)務邏輯函數(shù)锐膜;
通過成員變量mRemote= new BpBinder(0)進行Binder通信工作。
BpBinder通過handler來指向所對應BBinder, 在整個Binder系統(tǒng)中handle=0代表ServiceManager所對應的BBinder弛房。
5.1 模板函數(shù)
Native層的Binder架構,通過如下兩個宏,非常方便地創(chuàng)建了new Bp##INTERFACE(obj):
例如:
等價于:
.....