首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Android之SystemServer介绍(一)

Android之SystemServer介绍(一)

作者头像
李小白是一只喵
发布2021-03-12 11:56:46
发布2021-03-12 11:56:46
6510
举报
文章被收录于专栏:算法微时光算法微时光

image.png

目录

Android之zygote源码剖析(一)

Android之zygote源码剖析(二)

Android之zygote源码剖析(三)

Android之SystemServer介绍(一)

SystemServer

从前文中可以看到,Zygote是孵化器,SystemServer进程是由Zygote进程孵化出来的。也就是SystemServer是Zygote进程fork出来的。

SystemServer是Android系统的核心之一,大部分Android提供的服务都在该进程中。

比如:ActivityManagerService(AMS),WindowManagerService(WMS),PackagManagerService(PMS)这些系统服务都是以一个线程的方式存在Systemserver进程中。

从上文我们看到ZygoteInit类中执行startSystemServer后,启动SystemServer进程后,会执行handleSystemServerProcess函数:

代码语言:javascript
复制
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {

        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Os.umask(S_IRWXG | S_IRWXO);

        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        // 从环变量获取systemServerClasspath
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);
            ……
        }

        if (parsedArgs.invokeWith != null) {
            String[] args = parsedArgs.remainingArgs;
            ……
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                // 创建PathClassLoader,用于加载类
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }

handleSystemServerProcess函数主要做了两件事情:

  1. 创建PathClassLoader(加载java类使用)
  2. 执行 ZygoteInit.zygoteInit

ZygoteInit.zygoteInit代码如下:

代码语言:javascript
复制
    public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        // 启动binder线程池
        ZygoteInit.nativeZygoteInit();
        // 启动systemserver的main函数
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

这段代码也主要干两件事:

  1. 启动binder线程池
  2. 启动systemserver的main函数

启动binder线程池

nativeZygoteInit函数是native函数,通过JNI调用,函数位于

AndroidRuntime.cpp内:

代码语言:javascript
复制
static AndroidRuntime* gCurRuntime = NULL;

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

onZygoteInit是个虚函数,实现在app_process.cpp里:

代码语言:javascript
复制
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        // 启动线程池
        proc->startThreadPool();
    }

这里就启动了binder线程池。

启动systemserver的main函数

接下来看下applicationInit(RuntimeInit.java

)函数:

代码语言:javascript
复制
    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {

        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            return;
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        // 主要执行了这个函数
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

继续跟踪invokeStaticMain函数:

代码语言:javascript
复制
   private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        Class<?> cl;

        try {
            // 传入参数为com.android.server.SystemServer
            // 加载类进入内存
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            // 获取SystemServer类中的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        // 执行main函数
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

从这里就执行到了SystemServer的mian函数。

classname的定义在startSystemServer函数中:

代码语言:javascript
复制
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };

今天就到这里,散会。_

image.png

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • SystemServer
  • 启动binder线程池
  • 启动systemserver的main函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档