Android系統的Binder機制之四——系統Service

 前面咱們已經介紹了Android Binder機制的Service ManagerService對象代理1Service對象代理2。本文將介紹一下Android機制的另一個重要部分——系統Service。android

一、系統Service實例——Media server

    首先咱們先看一下Android一個實例Media Service,代碼位於framework/base/media/mediaserver/main_mediaserver.cpp文件:cookie

 1: // System headers required for setgroups, etc.

 2: #include <sys/types.h>

 3: #include <unistd.h>

 4: #include <grp.h>

 5: 

 6: #include <binder/IPCThreadState.h>

 7: #include <binder/ProcessState.h>

 8: #include <binder/IServiceManager.h>

 9: #include <utils/Log.h>

 10: 

 11: #include <AudioFlinger.h>

 12: #include <CameraService.h>

 13: #include <MediaPlayerService.h>

 14: #include <AudioPolicyService.h>

 15: #include <private/android_filesystem_config.h>

 16: 

 17: using namespace android;

 18: 

 19: int main(int argc, char** argv)

 20: {

 21:     sp<ProcessState> proc(ProcessState::self());

 22:     sp<IServiceManager> sm = defaultServiceManager();

 23:     LOGI("ServiceManager: %p", sm.get());

 24:     AudioFlinger::instantiate();

 25:     MediaPlayerService::instantiate();

 26:     CameraService::instantiate();

 27:     AudioPolicyService::instantiate();

 28:     ProcessState::self()->startThreadPool();

 29:     IPCThreadState::self()->joinThreadPool();

 30: }

    咱們發現Media Server是一個進程,而且該程序的實現表面上也挺簡單,其實並不簡單,讓咱們慢慢分析一下Media Server。框架

一、第一句建立建立一個ProcessState的引用,可是這個對象後面並無被調用到,那麼爲何建立呢?請回想一下我在博文《Android系統的Binder機制之二——服務代理對象(1)》中介紹ProcessState對象時提到:若是一個進程要使用Binder機制,那麼他的進程中必需要建立一個ProcessState對象來負責管理Service的代理對象。

二、第二句調用defaultServiceManager得到一個Service Manager代理對象,我在《
Android系統的Binder機制之二——服務代理對象(1)》已經對此有了詳細的介紹這裏就不贅述了。

三、後面幾行都是建立具體的Service,咱們展開以後發現都是一些調用Service Manager的addService進行註冊的函數,以AudioFlinger爲例,instantiate代碼以下:
函數

 1: void AudioFlinger::instantiate() {

 2:     defaultServiceManager()->addService(

 3:             String16("media.audio_flinger"), new AudioFlinger());

 4: }

四、最後調用ProcessState的startThreadPool方法和IPCThreadState的joinThreadPool使Media Server進入等待請求的循環當中。ui

    咱們能夠看出一個進程中能夠有多個Service,Media Server這個進程中就存在AudioFlinger,MediaPlayerService,CameraService,AudioPolicyService四個Service。spa

二、系統Service的基礎——BBinder

    咱們仔細查看一下Media Server中定義的四個Service咱們將會發現他們都是繼承自BBinder,而BBinder又繼承自IBinder接口,詳細狀況請自行查看他們的代碼。每一個Service都改寫了BBinder的onTransact虛函數,當用戶發送請求到達Service時,框架將會調用Service的onTransact函數,後面咱們將會詳細的介紹這個機制。.net

三、Service註冊

    每一個Service都須要向「大管家」Service Manager進行註冊,調用Service Manager的addService方法註冊。這樣Service Manager將會運行客戶端查詢和獲取該Service(代理對象),而後客戶端就能夠經過該Service的代理對象請求該Service的服務。代理

四、Service進入等待請求的循環

    每一個Service必需要進入死循環,等待客戶端請求的到達,本例中最後兩句就是使Service進行等待請求的循環之中。ProcessState的startThreadPool方法最終調用的也是IPCThreadState的joinThreadPool方法,具體請查看代碼。IPCThreadState的joinThreadPool方法的代碼以下:unix

 1: void IPCThreadState::joinThreadPool(bool isMain)

 2: {

 3:       ......

 4:       do {

 5:         int32_t cmd;

 6:

 7:         ......

 8: 

 9:         // now get the next command to be processed, waiting if necessary

 10:         result = talkWithDriver();

 11:         if (result >= NO_ERROR) {

 12:             ......

 13: 

 14:             result = executeCommand(cmd);

 15:         }

 16:

 17:         ......

 18:     } while (result != -ECONNREFUSED && result != -EBADF);

 19: 

 20:     ......

 21: }

    Service在IPCThreadState的joinThreadPool方法中,調用talkWithDriver方法和Binder驅動進行交互,讀取客戶端的請求。當客戶端請求到達以後調用executeCommand方法進行處理。code

    咱們再看一下Service怎樣處理客戶端的請求?咱們們查看一下executeCommand方法的源碼:

 1: status_t IPCThreadState::executeCommand(int32_t cmd)

 2: {

 3:     BBinder* obj;

 4:     RefBase::weakref_type* refs;

 5:     status_t result = NO_ERROR;

 6:

 7:     switch (cmd) {

 8:         ......

 9:          case BR_TRANSACTION:

 10:         {

 11:             ......

 12:             if (tr.target.ptr) {

 13:                 sp<BBinder> b((BBinder*)tr.cookie);

 14:                 const status_t error = b->transact(tr.code, buffer, &reply, 0);

 15:                 if (error < NO_ERROR) reply.setError(error);

 16:

 17:             }

 18:             ......

 19:         }

 20:         break;

 21:

 22:     ......

 23:     }

 24: 

 25:     if (result != NO_ERROR) {

 26:         mLastError = result;

 27:     }

 28:

 29:     return result;

 30: }

能夠看到IPCThreadState將會直接調用BBinder的transact方法來處理客戶端請求,咱們再看一下BBinder的transact方法:

 1: status_t BBinder::transact(

 2:     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

 3: {

 4:     data.setDataPosition(0);

 5: 

 6:     status_t err = NO_ERROR;

 7:     switch (code) {

 8:         case PING_TRANSACTION:

 9:             reply->writeInt32(pingBinder());

 10:             break;

 11:         default:

 12:             err = onTransact(code, data, reply, flags);

 13:             break;

 14:     }

 15: 

 16:     if (reply != NULL) {

 17:         reply->setDataPosition(0);

 18:     }

 19: 

 20:     return err;

 21: }

咱們發現他將會叫用本身的虛函數onTransact。咱們前面提到全部的Service都集成自BBinder,而且都改寫了onTransact虛函數。那麼IPCThreadState將會調用Service定義onTransact方法來響應客戶請求。

五、結論

    本文簡單介紹了一下系統Service的原理,臺灣的高煥堂先生有一篇文章,手把手教怎樣實現一個系統Service,你能夠在個人博文《(轉)高煥堂——Android框架底層結構知多少?》中找到。

相關文章
相關標籤/搜索