一愁拭、 獲取服務(wù)
在Native層的服務(wù)注冊,我們選擇以media為例來展開講解亏吝,先來看看media的類關(guān)系圖敛苇。
1.1 類圖
圖解:
藍(lán)色: 代表獲取MediaPlayerService服務(wù)相關(guān)的類;
綠色: 代表Binder架構(gòu)中與Binder驅(qū)動通信過程中的最為核心的兩個類顺呕;
紫色: 代表注冊服務(wù)和獲取服務(wù)的公共接口/父類;
二. 獲取Media服務(wù)
2.1 getMediaPlayerService
[-> framework/av/media/libmedia/IMediaDeathNotifier.cpp]
其中defaultServiceManager()過程在上一篇文章獲取ServiceManager已講過括饶,返回BpServiceManager株茶。
在請求獲取名為”media.player”的服務(wù)過程中,采用不斷循環(huán)獲取的方法图焰。由于MediaPlayerService服務(wù)可能還沒向ServiceManager注冊完成或者尚未啟動完成等情況启盛,故則binder返回為NULL,休眠0.5s后繼續(xù)請求技羔,直到獲取服務(wù)為止僵闯。
2.2 BpSM.getService
[-> IServiceManager.cpp ::BpServiceManager]
通過BpServiceManager來獲取MediaPlayer服務(wù):檢索服務(wù)是否存在,當(dāng)服務(wù)存在則返回相應(yīng)的服務(wù)藤滥,當(dāng)服務(wù)不存在則休眠1s再繼續(xù)檢索服務(wù)鳖粟。該循環(huán)進行5次。為什么是循環(huán)5次呢拙绊,這估計跟Android的ANR時間為5s相關(guān)向图。如果每次都無法獲取服務(wù),循環(huán)5次标沪,每次循環(huán)休眠1s榄攀,忽略checkService()的時間,差不多就是5s的時間
2.3 BpSM.checkService
[-> IServiceManager.cpp ::BpServiceManager]
檢索指定服務(wù)是否存在, 其中remote()為BpBinder金句。
2.4 BpBinder::transact
[-> BpBinder.cpp]
Binder代理類調(diào)用transact()方法檩赢,真正工作還是交給IPCThreadState來進行transact工作,
2.4.1 IPCThreadState::self
[-> IPCThreadState.cpp]
TLS是指Thread local storage(線程本地儲存空間)违寞,每個線程都擁有自己的TLS贞瞒,并且是私有空間,線程之間不會共享趁曼。通過pthread_getspecific/pthread_setspecific函數(shù)可以獲取/設(shè)置這些空間中的內(nèi)容憔狞。從線程本地存儲空間中獲得保存在其中的IPCThreadState對象。
2.4.2 IPCThreadState初始化
[-> IPCThreadState.cpp]
每個線程都有一個IPCThreadState彰阴,每個IPCThreadState中都有一個mIn瘾敢、一個mOut。成員變量mProcess保存了ProcessState變量(每個進程只有一個)。
mIn 用來接收來自Binder設(shè)備的數(shù)據(jù)簇抵,默認(rèn)大小為256字節(jié)庆杜;
mOut用來存儲發(fā)往Binder設(shè)備的數(shù)據(jù),默認(rèn)大小為256字節(jié)碟摆。
2.5 IPC::transact
[-> IPCThreadState.cpp]
2.6 IPC.writeTransactionData
[-> IPCThreadState.cpp]
其中handle的值用來標(biāo)識目的端晃财,注冊服務(wù)過程的目的端為service manager,此處handle=0所對應(yīng)的是binder_context_mgr_node對象典蜕,正是service manager所對應(yīng)的binder實體對象断盛。binder_transaction_data結(jié)構(gòu)體是binder驅(qū)動通信的數(shù)據(jù)結(jié)構(gòu),該過程最終是把Binder請求碼BC_TRANSACTION和binder_transaction_data結(jié)構(gòu)體寫入到mOut愉舔。
2.7 IPC.waitForResponse
[-> IPCThreadState.cpp]
2.8 IPC.talkWithDriver
[-> IPCThreadState.cpp]
binder_write_read結(jié)構(gòu)體用來與Binder設(shè)備交換數(shù)據(jù)的結(jié)構(gòu), 通過ioctl與mDriverFD通信钢猛,是真正與Binder驅(qū)動進行數(shù)據(jù)讀寫交互的過程。 先向service manager進程發(fā)送查詢服務(wù)的請求(BR_TRANSACTION)轩缤,見Binder系列3—啟動ServiceManager命迈。當(dāng)service manager進程收到該命令后,會執(zhí)行do_find_service() 查詢服務(wù)所對應(yīng)的handle火的,然后再binder_send_reply()應(yīng)答 發(fā)起者壶愤,發(fā)送BC_REPLY協(xié)議,然后調(diào)用binder_transaction()馏鹤,再向服務(wù)請求者的Todo隊列 插入事務(wù)征椒。
接下來,再看看binder_transaction過程湃累。
2.8.1 binder_transaction
這個過程非常重要陕靠,分兩種情況來說:
當(dāng)請求服務(wù)的進程與服務(wù)屬于不同進程,則為請求服務(wù)所在進程創(chuàng)建binder_ref對象脱茉,指向服務(wù)進程中的binder_node;
當(dāng)請求服務(wù)的進程與服務(wù)屬于同一進程剪芥,則不再創(chuàng)建新對象,只是引用計數(shù)加1琴许,并且修改type為BINDER_TYPE_BINDER或BINDER_TYPE_WEAK_BINDER税肪。
2.8.2 binder_thread_read
2.9 readStrongBinder
[-> Parcel.cpp]
2.9.1 unflatten_binder
[-> Parcel.cpp]
2.9.2 getStrongProxyForHandle
[-> ProcessState.cpp]
readStrongBinder的功能是flat_binder_object解析并創(chuàng)建BpBinder對象.
2.9.3 lookupHandleLocked
根據(jù)handle值來查找對應(yīng)的handle_entry.
二. 總結(jié)
請求服務(wù)(getService)過程,就是向servicemanager進程查詢指定服務(wù)榜田,當(dāng)執(zhí)行binder_transaction()時益兄,會區(qū)分請求服務(wù)所屬進程情況。
當(dāng)請求服務(wù)的進程與服務(wù)屬于不同進程箭券,則為請求服務(wù)所在進程創(chuàng)建binder_ref對象净捅,指向服務(wù)進程中的binder_node;
最終readStrongBinder(),返回的是BpBinder對象辩块;
當(dāng)請求服務(wù)的進程與服務(wù)屬于同一進程蛔六,則不再創(chuàng)建新對象荆永,只是引用計數(shù)加1,并且修改type為BINDER_TYPE_BINDER或BINDER_TYPE_WEAK_BINDER国章。
最終readStrongBinder()具钥,返回的是BBinder對象的真實子類;