展会信息港展会大全

Android系统Service Binder机制 系统服务
来源:互联网   发布日期:2016-01-13 22:20:56   浏览:2390次  

导读:前面我们已经介绍了Android Binder机制的Service Manager,Service对象代理1,Service对象代理2。本文将介绍一下Android机制的另外一个重要部分系统Service。1、系统Service实例Media server 首先我......

前面我们已经介绍了Android Binder机制的Service Manager,Service对象代理1,Service对象代理2。本文将介绍一下Android机制的另外一个重要部分系统Service。

1、系统Service实例Media server

首先我们先看一下Android一个实例Media Service,代码位于framework/base/media/mediaserver/main_mediaserver.cpp文件:

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。

1、第一句创建创建一个ProcessState的引用,但是这个对象后面并没有被调用到,那么为什么创建呢?请回想一下我在博文《Android系统的Binder机制之二服务代理对象(1)》中介绍ProcessState对象时提到:如果一个进程要使用Binder机制,那么他的进程中必须要创建一个ProcessState对象来负责管理Service的代理对象。

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

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。

2、系统Service的基础BBinder

我们仔细查看一下Media Server中定义的四个Service我们将会发现他们都是继承自BBinder,而BBinder又继承自IBinder接口,详细情况请自行查看他 们的代码。每个Service都改写了BBinder的onTransact虚函数,当用户发送请求到达Service时,框架将会调用Service的 onTransact函数,后面我们将会详细的介绍这个机制。

3、Service注册

每个Service都需要向 大管家 Service Manager进行注册,调用Service Manager的addService方法注册。这样Service Manager将会运行客户端查询和获取该Service(代理对象),然后客户端就可以通过该Service的代理对象请求该Service的服务。

4、Service进入等待请求的循环

每个Service必须要进入死循环,等待客户端请求的到达,本例中最后两句就是使Service进行等待请求的循环之中。ProcessState的 startThreadPool方法最终调用的也是IPCThreadState的joinThreadPool方法,具体请查看代码。 IPCThreadState的joinThreadPool方法的代码如下:

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方法进行处理。

我们再看一下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方法来响应客户请求。

5、结论

本文简单介绍了一下系统Service的原理,台湾的高焕堂先生有一篇文章,手把手教怎样实现一个系统Service,你可以在我的博文《(转)高焕堂Android框架底层结构知多少?》中找到。

赞助本站

人工智能实验室

相关热词: 系统Service 系统服务

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港