前面咱們已經介紹了Android Binder機制的Service Manager,Service對象代理1,Service對象代理2。本文將介紹一下Android機制的另一個重要部分——系統Service。android
首先咱們先看一下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
咱們仔細查看一下Media Server中定義的四個Service咱們將會發現他們都是繼承自BBinder,而BBinder又繼承自IBinder接口,詳細狀況請自行查看他們的代碼。每一個Service都改寫了BBinder的onTransact虛函數,當用戶發送請求到達Service時,框架將會調用Service的onTransact函數,後面咱們將會詳細的介紹這個機制。.net
每一個Service都須要向「大管家」Service Manager進行註冊,調用Service Manager的addService方法註冊。這樣Service Manager將會運行客戶端查詢和獲取該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框架底層結構知多少?》中找到。