一個進程如何將service加到另一個進程(系統servicemanager)中去,涉及到進程間的通信

defaultServiceManager()調用addService添加服務的執行流程:---------------------------------------

1、

defaultServiceManager()->addService(

String16("media.player"), newMediaPlayerService());

因為defaultServiceManager()返回ServiceManager的代理BpServiceManager,所以這里調用BpServiceManager的addService函數。

2、addService函數中分析

將調用,

status_t err =

remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

因為remote()函數是BpServiceManager基類BpRefBase的函數,它返回mRemote,這個值我們知道保存了一個BpBinder對象,所以將調用BpBinder的transact函數。

3、在BpBinder::transact函數中

status_t BpBinder::transact(

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

有如下實現,

status_t status = IPCThreadState::self()->transact(

mHandle, code, data, reply, flags);

因此它又將調用IPCThreadState的transact函數。

4、在IPCThreadState的transact函數中,

status_t IPCThreadState::transact(int32_t

handle,

uint32_tcode, const Parcel& data,

Parcel*reply, uint32_t flags)

將先掉用

err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data,NULL);

發送數據,然后使用,

err = waitForResponse(reply);

等待處理的結果,最后將處理結果err和reply分別通過返回值和參數返回。

5、在函數IPCThreadState::writeTransactionData中,將數據封裝到mOut變量中。

6、在函數IPCThreadState::waitForResponse中,

起一個循環,首先調用talkWithDriver將mOut寫給低層Binder,然后通過mIn將結果傳出。

其次使用switch判斷傳出的消息,最后執行IPCThreadState::executeCommand對各種消息進行處理。

7、函數IPCThreadState::executeCommand,注意其中的幾個消息的處理,

case BR_TRANSACTION:處理中

if (tr.target.ptr) {

spb((BBinder*)tr.cookie);

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

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

}

調用了BBinder對象b,這個對象就是BnServiceManager中的那個。

case BR_DEAD_BINDER:

{

BpBinder *proxy = (BpBinder*)mIn.readInt32();

proxy->sendObituary();

mOut.writeInt32(BC_DEAD_BINDER_DONE);

mOut.writeInt32((int32_t)proxy);

} break;

收到Binder發來Service死掉的消息,由BpBinder進行處理。

case BR_SPAWN_LOOPER:

mProcess->spawnPooledThread(false);

break;

收到驅動的指示,創建一個新線程,用于和Binder通信。

8、函數IPCThreadState::talkWithDriver

通過ioctl和Binder驅動進行消息傳遞。

if (ioctl(mProcess->mDriverFD,

BINDER_WRITE_READ, &bwr) >= 0)

err = NO_ERROR;

else

err = -errno;

9、

使用函數ProcessState::startThreadPool在進程中開一個線程。

void ProcessState::startThreadPool()

{

AutoMutex _l(mLock);

if (!mThreadPoolStarted) {

mThreadPoolStarted = true;

spawnPooledThread(true);

}

}

調用spawnPooledThread(true)創建一個線程。注意,isMain是true.

線程的名稱用

int32_t s = android_atomic_add(1, &mThreadPoolSeq);

char buf[32];

sprintf(buf, "Binder Thread #%d", s);

指定。

可以看出,和Binder相關的線程都是有ProcessState啟動的,而每個進程和Binder通訊時,只有一個ProcessState,但可能會有多個Binder Thread。

10、使用函數IPCThreadState::self()->joinThreadPool()將創建的線程添加到線程池。

在其內部調用

mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

其實也是啟動一個線程。

11、以上都是由代理BpServiceManager傳遞的,BnServiceManager并未顯示創建,但肯定是有的。有個和它一樣的功能由系統創建,在文件service_manager.c的main中進行了創建,它直接和Binder打交道。

12、

MediaPlayerService的Client端實現。

通過函數IMediaDeathNotifier::getMediaPlayerService()獲得MediaPlayerService的BpMediaPlayerService。

首先通過binder =

sm->getService(String16("media.player"));得到系統的BpBinder,然后利用

sMediaPlayerService =

interface_cast(binder);

生成系統的BpMediaPlayerService,得到服務的代理。

mso-h????-

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容