ServiceManager原理分析

ServiceManager

简介

Android系统对外提供了非常丰富的服务功能, 例如Java层的ActivityManagerService,WindowManagerService,PackageManagerService服务, Native层的SurfaceFlinger,AudioFlinger服务等,这么多服务有一个统一的地方来管理这些服务,这个管理的地方就是ServiceManager。当系统进程需要增加一个服务时,只需要将服务名和服务实体告诉ServiceManager就可以完成,这便是服务注册过程;当应用进程需要使用某个服务,只需要将服务名告诉ServiceManager就可以查询到服务的代理对象,通过代理对象来使用服务,这便是服务查询过程。

如图5-1所示, AMS注册过程就是告诉ServiceManager进程,ActivityManagerService服务实体运行在system_server进程,服务名叫“activity”,则在servicemanager进程的svclist列表中增加一条svcinfo记录, 里面主要记录着服务名以及相对应的handle值。查询AMS服务的过程,向ServiceManager进程查询一个服务名为“activity”的服务,ServiceManager通过检索svclist列表会找到所对应的服务在该进程中的handle值,有了这个handle值,经过Binder驱动就能生成AMS服务实体的代理对象,有了代理对象就可以使用AMS服务,比如经常使用的startService()方法就使用了AMS服务。
ServiceManager原理分析_第1张图片

ServiceManager进程启动流程

ServiceManager进程是由init进程通过解析servicemanager.rc文件而创建的,servicemanager.rc文件内容如下:

service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart audioserver
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart inputflinger
    onrestart restart drm
    onrestart restart cameraserver
    onrestart restart keystore
    onrestart restart gatekeeperd
    writepid /dev/cpuset/system-background/tasks
    shutdown critical

init进程解析servicemanager.rc文件后,找到servicemanager进程所对应的可执行程序/system/bin/servicemanager,/system/bin/servicemanager可执行程序是根据/frameworks/base/cmds/servicemanager/目录下的service_manager.c、binder.c、binder.h、Android.mk等几个文件编译而成的。启动入口是service_manager.c的main()方法:

// service_manager.c
int main(int argc, char **argv) {
    struct binder_state *bs;
    char *driver;
    if (argc > 1) {
        driver = argv[1];
    } else {
        driver = "/dev/binder"; // 默认的Binder设备节点
    }

    //Step 1: 打开binder驱动,申请128k字节内存,即mmap内存大小128K
    bs = binder_open(driver, 128*1024);
    ...

    //Step 2: 成为上下文管理者
    if (binder_become_context_manager(bs)) {
        return -1;
    }
    ...

    //Step 3: 进入无限循环,处理client端发来的请求
    binder_loop(bs, svcmgr_handler);
    return 0;
}

启动过程主要划分为以下几个阶段:

  • 首先,调用binder_open()方法来打开binder驱动,默认地采用/dev/binder设备节点,申请地内存空间大小为128KB;
  • 其次,调用binder_become_context_manager()方法,将自己注册成为binder服务的上下文管理者;
  • 最后,调用binder_loop()方法进入无限循环,作为守护进程,随时等待处理client端发来的请求。

下图描述了这一过程:
ServiceManager原理分析_第2张图片

java层的ServiceManager

参考:
系统服务管理者:ServiceManager进程
ServiceManager管家
ServiceManager启动流程

https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/base/core/java/android/os/ServiceManager.java

https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/native/cmds/servicemanager/service_manager.c
https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks/native/cmds/servicemanager/binder.c

你可能感兴趣的:(Android面试题,Android)