zoukankan      html  css  js  c++  java
  • 对于ServiceManager的理解

    ServiceManager是什么?

    ServiceManager是binder服务的大管家,由Init进程解析init.rc文件创建,其本身也是一个Binder服务,但并没有采用libbinder中的多线程模型来与Binder驱动通信,而是自行编写了binder.c直接和Binder驱动来通信,并且只有一个循环binder_loop来进行读取和处理事务,这样的好处是简单而高效。

    ServiceManager的作用?

    ServiceManager的作用相对简单,主要是“注册和查询”服务。

    ServiceManager的工作流程?

    启动流程

    Init进程解析配置文件,其所对应的可执行程序/system/bin/servicemanager,所对应的源文件是service_manager.c

    service servicemanager /system/bin/servicemanager
        class core
        user system
        group system
        critical
        onrestart restart healthd
        onrestart restart zygote
        onrestart restart media
        onrestart restart surfaceflinger
        onrestart restart drm
    

    启动Service Manager的入口函数是service_manager.c中的main()方法,代码如下:

    int main(int argc, char **argv) {
        struct binder_state *bs;
        //打开binder驱动,申请128k字节大小的内存空间 【见小节2.2】
        bs = binder_open(128*1024);
        ...
    
        //成为上下文管理者 【见小节2.3】
        if (binder_become_context_manager(bs)) {
            return -1;
        }
    
        selinux_enabled = is_selinux_enabled(); //selinux权限是否使能
        sehandle = selinux_android_service_context_handle();
        selinux_status_open(true);
    
        if (selinux_enabled > 0) {
            if (sehandle == NULL) {  
                abort(); //无法获取sehandle
            }
            if (getcon(&service_manager_context) != 0) {
                abort(); //无法获取service_manager上下文
            }
        }
        ...
    
        //进入无限循环,处理client端发来的请求 【见小节2.4】
        binder_loop(bs, svcmgr_handler);
        return 0;
    }
    

    主要有下面三个流程:

    • 打开binder驱动:binder_open;
    • 注册成为binder服务的大管家:binder_become_context_manager;
    • 进入无限循环,处理client端发来的请求:binder_loop;

    添加服务

    ServiceManager对应的Java类是ServiceManager.java,Android中的系统服务注册正式通过这个类完成的。我们看看它的addService方法:

      public static void addService(String name, IBinder service) {
            try {
                getIServiceManager().addService(name, service, false);
            } catch (RemoteException e) {
                Log.e(TAG, "error in addService", e);
            }
        }
    

    再看看getIServiceManager()方法:

        private static IServiceManager getIServiceManager() {
            if (sServiceManager != null) {
                return sServiceManager;
            }
    
            // Find the service manager
            sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
            return sServiceManager;
        }
    

    可以看到是通过BinderInternal.getContextObject()转换成IServiceManager这个binder代理类的,我们看看它的方法介绍:

        /**
         * Return the global "context object" of the system.  This is usually
         * an implementation of IServiceManager, which you can use to find
         * other services.
         */
        public static final native IBinder getContextObject();
    

    看注释可以知道这个返回的IBinder就是IServiceManager的binder代理类,为什么要这么做呢?因为其他进程和ServiceManager通讯的目的是为了注册或者查询服务,但是这些进程和ServiceManager又是属于不同但进程,这里又需要跨进程通讯,所以Native层就干脆把IServiceManager的binder放在固定的一个位置,其他进程可以直接拿到这个IBinder对象。

  • 相关阅读:
    计算机基础
    程序的控制结构
    day 04作业
    数据类型-数据类型
    第二次作业
    第二次博客
    第一篇博客
    原生js与ajax应用
    ajax原理及其优缺点
    jQuery动画
  • 原文地址:https://www.cnblogs.com/monsterdev/p/12685105.html
Copyright © 2011-2022 走看看