Android系统的Binder机制之四(系统Service篇)

前面我们已经介绍了Android Binder机制的 Service ManagerService对象代理(上)Service对象代理(下)。本文将介绍一下Android机制的另外一个重要部分——系统Service。
一、系统Service实例——Media server
首先我们先看一下Android一个实例Media Service,代码位于 framework/base/media/mediaserver/main_mediaserver.cpp 文件:
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>

#include <AudioFlinger.h>
#include <CameraService.h>
#include <MediaPlayerService.h>
#include <AudioPolicyService.h>
#include <private/android_filesystem_config.h>

using namespace android;

int main (int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
我们发现 Media Server 是一个进程,并且该程序的实现表面上也挺简单,其实并不简单,让我们慢慢分析一下Media Server。
1、第一句创建创建一个ProcessState的引用,但是这个对象后面并没有被调用到,那么为什么创建呢?回想一下《

Android系统的Binder机制之二(服务代理对象 上篇)》中介绍ProcessState对象时提到:如果一个进程要使用Binder机制,

那么他的进程中必须要创建一个ProcessState对象来负责管理Service的代理对象。

2、第二句调用defaultServiceManager获得一个Service Manager代理对象,
我在《 Android系统的Binder机制之二(服务代理对象 上篇) 》已经对此有了详细的介绍这里就不赘述了。

3、后面几行都是创建具体的Service,我们展开之后发现都是一些调用Service Manager的addService进行注册的函数,以AudioFlinger为例,instantiate代码如下:

1: void AudioFlinger::instantiate() {
2: defaultServiceManager()->addService(
3: String16("media.audio_flinger"), new AudioFlinger());
4: }
4、最后调用ProcessState的 startThreadPool 方法和IPCThreadState的 joinThreadPool 使Media Server进入等待请求的循环当中。
我们可以看出一个进程中可以有多个Service,Media Server这个进程中就存在AudioFlinger,MediaPlayerService,CameraService,AudioPolicyService四个Service
二、系统Service的基础——BBinder
我们仔细查看一下Media Server中定义的四个Service我们将会发现他们都是继承自BBinder,而BBinder又继承自IBinder接口,详细情况请自行查看他们的代码。每个Service都改写了BBinder的onTransact虚函数,当用户发送请求到达Service时,框架将会调用Service的onTransact函数,后面我们将会详细的介绍这个机制。
三、Service注册
每个Service都需要向“大管家” Service Manager 进行注册,调用Service Manager的 addService 方法注册。这样Service Manager将会运行客户端查询和获取该Service(代理对象),然后客户端就可以通过该Service的代理对象请求该Service的服务。
四、Service进入等待请求的循环
每个Service必须要进入死循环,等待客户端请求的到达,本例中最后两句就是使Service进行等待请求的循环之中。
ProcessState startThreadPool 方法的代码如下
void ProcessState:: startThreadPool ()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState:: spawnPooledThread (bool isMain)
{
if (mThreadPoolStarted) {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
char buf[32];
sprintf(buf, "Binder Thread #%d", s);
LOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);
t->run(buf);
}
}
IPCThreadState的joinThreadPool方法的代码如下

void IPCThreadState:: joinThreadPool (bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
// This thread may have been spawned by a thread that was in the background
// scheduling group, so first we will make sure it is in the default/foreground
// one to avoid performing an initial transaction in the background.
androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
status_t result;
do {
int32_t cmd;
// When we've cleared the incoming command queue, process any pending derefs
if (mIn.dataPosition() >= mIn.dataSize()) {
size_t numPending = mPendingWeakDerefs.size();
if (numPending > 0) {
for (size_t i = 0; i < numPending; i++) {
RefBase::weakref_type* refs = mPendingWeakDerefs[i];
refs->decWeak(mProcess.get());
}
mPendingWeakDerefs.clear();
}

numPending = mPendingStrongDerefs.size();
if (numPending > 0) {
for (size_t i = 0; i < numPending; i++) {
BBinder* obj = mPendingStrongDerefs[i];
obj->decStrong(mProcess.get());
}
mPendingStrongDerefs.clear();
}
}
// now get the next command to be processed, waiting if necessary
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) continue;
cmd = mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing top-level Command: "
<< getReturnString(cmd) << endl;
}
result = executeCommand(cmd);
}
// After executing the command, ensure that the thread is returned to the
// default cgroup before rejoining the pool. The driver takes care of
// restoring the priority, but doesn't do anything with cgroups so we
// need to take care of that here in userspace. Note that we do make
// sure to go in the foreground after executing a transaction, but
// there are other callbacks into user code that could have changed
// our group so we want to make absolutely sure it is put back.
androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if (result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);

LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
(void*)pthread_self(), getpid(), (void*)result);
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
Service 在IPCThreadState的joinThreadPool方法中,调用talkWithDriver方法和Binder驱动进行交互,读取客户端的请求。当客户端请求到达之后调用executeCommand方法进行处理。
我们再看一下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方法:
status_t BBinder:: transact ( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default :
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
我们发现他将会叫用自己的虚函数onTransact。我们前面提到所有的Service都集成自 BBinder ,并且都改写了 onTransact 虚函数。那么IPCThreadState将会调用Service定义 onTransact 方法来响应客户请求。
五、结论
本文简单介绍了一下系统Service的原理,台湾的高焕堂先生有一篇文章,手把手教怎样实现一个系统Service,你可以在我的博文《 (转)高焕堂——Android框架底层结构知多少?》中找到。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值