Android 面試題之介紹源碼中binder機制

面試問到這個,其實就是讓你說一下binder是干什么的,Service Manager是如何成為一個守護進程的

Binder是干什么的

Binder -- 一種進程間通信(IPC)機制, 基于OpenBinder

    1. Client、Server和Service Manager實現(xiàn)在用戶空間中,Binder驅(qū)動程序?qū)崿F(xiàn)在內(nèi)核空間中
    1. Binder驅(qū)動程序和Service Manager在Android平臺中已經(jīng)實現(xiàn),開發(fā)者只需要在用戶空間實現(xiàn)自己的Client和Server
    1. Binder驅(qū)動程序提供設(shè)備文件/dev/binder與用戶空間交互,Client、Server和Service Manager通過open和ioctl文件操作函數(shù)與Binder驅(qū)動程序進行通信
    1. Client和Server之間的進程間通信通過Binder驅(qū)動程序間接實現(xiàn)
    1. Service Manager是一個守護進程,用來管理Server,并向Client提供查詢Server接口的能力

1.Service Manager是如何成為一個守護進程的?即Service Manager是如何告知Binder驅(qū)動程序它是Binder機制的上下文管理者。

Service Manager,它是整個Binder機制的守護進程,用來管理開發(fā)者創(chuàng)建的各種Server,并且向Client提供查詢Server遠程接口的功能

既然Service Manager組件是用來管理Server并且向Client提供查詢Server遠程接口的功能,那么,Service Manager就必然要和Server以及Client進行通信了。我們知道,Service Manger、Client和Server三者分別是運行在獨立的進程當中,這樣它們之間的通信也屬于進程間通信了,而且也是采用Binder機制進行進程間通信,因此,Service Manager在充當Binder機制的守護進程的角色的同時,也在充當Server的角色,然而,它是一種特殊的Server,下面我們將會看到它的特殊之處

Service Manager在用戶空間的源代碼位于frameworks/base/cmds/servicemanager目錄下,主要是由binder.h、binder.c和service_manager.c三個文件組成。Service Manager的入口位于service_manager.c文件中的main函數(shù):

int main(int argc, char **argv)
{
    struct binder_state *bs;
    void *svcmgr = BINDER_SERVICE_MANAGER;

    bs = binder_open(128*1024);

    if (binder_become_context_manager(bs)) {
        LOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);
    return 0;
}

main函數(shù)主要有三個功能:一是打開Binder設(shè)備文件;二是告訴Binder驅(qū)動程序自己是Binder上下文管理者,即我們前面所說的守護進程;三是進入一個無窮循環(huán),充當Server的角色,等待Client的請求

2. Server和Client是如何獲得Service Manager接口的?即defaultServiceManager接口是如何實現(xiàn)的。

ServiceManager 作為守護進程,Service Manager的職責當然就是為Server和Client服務了。那么,Server和Client如何獲得Service Manager接口,進而享受它提供的服務呢?

Service Manager在Binder機制中既充當守護進程的角色,同時它也充當著Server角色,然而它又與一般的Server不一樣。對于普通的Server來說,Client如果想要獲得Server的遠程接口,那么必須通過Service Manager遠程接口提供的getService接口來獲得,這本身就是一個使用Binder機制來進行進程間通信的過程。而對于Service Manager這個Server來說,Client如果想要獲得Service Manager遠程接口,卻不必通過進程間通信機制來獲得,因為Service Manager遠程接口是一個特殊的Binder引用,它的引用句柄一定是0。

經(jīng)過一系列的調(diào)用...

回到defaultServiceManager函數(shù)中,最終結(jié)果為:

gDefaultServiceManager = new BpServiceManager(new BpBinder(0));

這樣,Service Manager遠程接口就創(chuàng)建完成了,它本質(zhì)上是一個BpServiceManager,包含了一個句柄值為0的Binder引用。

在Android系統(tǒng)的Binder機制中,Server和Client拿到這個Service Manager遠程接口之后怎么用呢?

對Server來說,就是調(diào)用IServiceManager::addService這個接口來和Binder驅(qū)動程序交互了,即調(diào)用BpServiceManager::addService 。而BpServiceManager::addService又會調(diào)用通過其基類BpRefBase的成員函數(shù)remote獲得原先創(chuàng)建的BpBinder實例,接著調(diào)用BpBinder::transact成員函數(shù)。在BpBinder::transact函數(shù)中,又會調(diào)用IPCThreadState::transact成員函數(shù),這里就是最終與Binder驅(qū)動程序交互的地方了?;貞浺幌虑懊娴念悎D,IPCThreadState有一個PorcessState類型的成中變量mProcess,而mProcess有一個成員變量mDriverFD,它是設(shè)備文件/dev/binder的打開文件描述符,因此,IPCThreadState就相當于間接在擁有了設(shè)備文件/dev/binder的打開文件描述符,于是,便可以與Binder驅(qū)動程序交互了。

對Client來說,就是調(diào)用IServiceManager::getService這個接口來和Binder驅(qū)動程序交互了。具體過程上述Server使用Service Manager的方法是一樣的,這里就不再累述了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容