一个进程如何将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����-

你可能感兴趣的:(一个进程如何将service加到另一个进程(系统servicemanager)中去,涉及到进程间的通信)