SystemServer进程浅析

前言

从上一篇文章Zygote进程浅析我们知道Zygote是孵化器,所有其他Dalvik虚拟机进程都是通过zygote孵化(fock)出来的;所以SystemServer进程是由Zygote进程fock(孵化)出来的。SystemServer进程是Android系统的核心之一,大部分Android提供的服务都在该进程中,SystemServer中运行的进程公共有六十多种,主要包括:ActivityManagerService(AMS),WindowManagerService(WMS),PackagManagerService(PMS)等;这些系统服务都是以一个线程的方式存在Systemserver进程中。

创建SystemServer进程

1:准备参数并且孵化SystemServer进程;

/**
 * Prepare the arguments and fork for the system server process.
 */
private static boolean startSystemServer(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {
	.......   
   
	//1 准备参数
    /* Hardcoded command line to start the system server */
    String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

    try {
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
		
		//2 fork出systemServer进程;
        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

		//3 初始化SystemServer进程
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

startSystemServer()方法中主要做了三件事:

  • 准备参数;
  • 调用forkSystemServer()方法fork出SystemServer进程;
  • 完成SystemServer进程的初始化工作;

现在来依次详细了解这三件事:
1)准备参数:SystemServer进程的进程Id和组Id均为为1000,进程名称为system_server,SystemServer的执行类是com.android.server.SystemServer。
2) 调用forkSystemServer()方法fork出SystemServer进程

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    VM_HOOKS.preFork();
    int pid = nativeForkSystemServer(
            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
    // Enable tracing as soon as we enter the system_server.
    if (pid == 0) {
        Trace.setTracingEnabled(true);
    }
    VM_HOOKS.postForkCommon();
    return pid;
}

如果返回pid为0 则创建成功,否者返回-1或者错误;在forkSystemServer()方法中调用native方法nativeForkSystemServer();

native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

3)调用handleSystemServerProcess()完成SystemServer进程的初始化工作;

 private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)throws ZygoteInit.MethodAndArgsCaller {

	//关闭并且清理zygote socket;
    closeServerSocket();

    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);
	//设置进程名称为system_server,由1)设置参数可知;
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        performSystemServerDexOpt(systemServerClasspath);
    }
	//由1)设置参数可知,invokeWith=null;
    if (parsedArgs.invokeWith != null) {
      ....
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createSystemServerClassLoader(systemServerClasspath,
                                               parsedArgs.targetSdkVersion);

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

		//将剩余的参数传递给SystemServer进程
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
}

来看下RuntimeInit类的zygoteInit()方法

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
    redirectLogStreams();
    commonInit();
    nativeZygoteInit();
    applicationInit(targetSdkVersion, argv, classLoader);
}

看下applicationInit()方法

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
   
    nativeSetExitWithoutCleanup(true);

	//设置VM参数
    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());
        // let the process exit
        return;
    }

    // The end of of the RuntimeInit event (see #zygoteInit).
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
	//剩下的参数被传递到main()方法中;
    // Remaining arguments are passed to the start class's static main
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

调用invokeStaticMain(),会调用SystemServer类的main()方法,但是不会直接调用main()方法,而是通过抛出异常new ZygoteInit.MethodAndArgsCaller(m, argv),在SystemServer类的main中捕获异常,

 catch (MethodAndArgsCaller caller) {
        caller.run();
 } catch (RuntimeException ex) {

在caller.run()中才会真正调用SystemServer或者ActivityThread的main()方法,就可以进入系统进程或者应用进程的启动流程;

由此可以知道所有其他Dalvik虚拟机进程都是通过zygote孵化(fock)出来的

SystemServer进程的初始化

先来看下main()方法,

public static void main(String[] args) {
    new SystemServer().run();
}

main()方法中创建SystemServer对象并调用run()方法

 private void run() {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices");
		//1 如果时间不正确,重新设置时间
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        //2 设置当前虚拟机的运行库路径
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // Enable the sampling profiler.
        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            mProfilerSnapshotTimer = new Timer();
            mProfilerSnapshotTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        SamplingProfilerIntegration.writeSnapshot("system_server", null);
                    }
                }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

        // Mmmmmm... more memory!
        VMRuntime.getRuntime().clearGrowthLimit();
		//3 设置虚拟机堆内存
        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        // Some devices rely on runtime fingerprint generation, so make sure
        // we've defined it before booting further.
        Build.ensureFingerprintProperty();

        // Within the system server, it is an error to access Environment paths without
        // explicitly specifying a user.
        Environment.setUserRequired(true);

        // Within the system server, any incoming Bundles should be defused
        // to avoid throwing BadParcelableException.
        BaseBundle.setShouldDefuse(true);

        // Ensure binder calls into the system always run at foreground priority.
        BinderInternal.disableBackgroundScheduling(true);

        // Increase the number of binder threads in system_server
        BinderInternal.setMaxThreads(sMaxBinderThreads);
		//设置线程优先级
        // Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
		//4 初始化主线程Looper
        Looper.prepareMainLooper();
		//5 装载libandroid_servers.so库
        // Initialize native services.
        System.loadLibrary("android_servers");

        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();
		//6 获取context
        // Initialize the system context.
        createSystemContext();
		//7 创建SystemServiceManager对象mSystemServiceManager
        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
	//8 开启服务
    // Start services.
    try {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    } catch (Throwable ex) {
      
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    // For debug builds, log event loop stalls to dropbox for analysis.
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
	//9 进入Loop循环,处理消息循环
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

可以看到run()方法中主要做了以下几件事:

  • 检验时间:如果当前时间早于1970年,则设置当前时间为1970年;
  • 设置当前虚拟机的运行库路径为persist.sys.dalvik.vm.lib.2;
  • 设置虚拟机的堆内存;设置虚拟机堆利用率为0.8;
  • 调用prepareMainLooper()初始化当前线程的Looper;
  • 加载libandroid_servers.so库;
  • 调用createSystemContext()获取context;
  • 创建SystemServiceManager对象mSystemServiceManager,负责系统Service的启动;
  • 调用startBootstrapServices();startCoreServices();startOtherServices();创建并运行所有Java服务;
  • 调用Looper.loop();开启消息循环;

1 先来看下createSystemContext()方法

 private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}

调用ActivityThread类的systemMain()方法获取activityThread对象,通过activityThread对象获取context;
来看下ActivityThread类的systemMain()方法

 public static ActivityThread systemMain() {
    // The system process on low-memory devices do not get to use hardware
    // accelerated drawing, since this can add too much overhead to the
    // process.
	//SystemServer在低内存的设备上不会开启硬件渲染
    if (!ActivityManager.isHighEndGfx()) {
        ThreadedRenderer.disable(true);//关闭硬件渲染
    } else {
        ThreadedRenderer.enableForegroundTrimming();
    }
    ActivityThread thread = new ActivityThread();//创建ActivityThread对象thread
    thread.attach(true);
    return thread;
}

从代码可以看出来,systemMain()方法中创建了一个ActivityThread对象。在applicationInit()方法中介绍了,启动应用最后执行的事ActivityThread类的main()方法。

ActivityThread类是应用程序的主线程类,最主要的作用是根据AMS(ActivityManagerService)负责调度和执activities、broadcasts和其它操作;

这里为什么要创建ActivityThread对象呢?实际上SystemServer不仅仅是一个单纯的后台进程,它也是运行着组件Service的进程,很多系统的对话框就是从SystemServer中显示出来的,因此,SystemServer本身也需要一个和APK应用类似的上下文环境,创建ActivityThread在SystemServer进程中,毕竟和普通进程中有区别,因此,这里调用attach()方法时参数为true,表示SystemServer中调用的;

 private void attach(boolean system) {//判断是否为系统进程
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {//非系统进程
       ....
    } else {//系统进程
        // Don't set application object here -- if the system crashes,
        // we can't display an alert, we just want to die die die.
		//设置在DDMS中看到的进程名称
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
			//创建Instrumentation对象
            mInstrumentation = new Instrumentation();
			//创建context对象
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
			//创建Application对象
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }
	.......
}

创建context对象时使用的mPackageInfo对象是通过getSystemContext()方法获取来的

public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}

调用ContextImpl类的createSystemContext();

static ContextImpl createSystemContext(ActivityThread mainThread) {
    LoadedApk packageInfo = new LoadedApk(mainThread);
    ContextImpl context = new ContextImpl(null, mainThread,
            packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    return context;
}

createSystemContext()方法中创建了一个LoadedApk对象,参数是ActivityThread;

 LoadedApk(ActivityThread activityThread) {
    mActivityThread = activityThread;
    mApplicationInfo = new ApplicationInfo();
    mApplicationInfo.packageName = "android";
    mPackageName = "android";
	.....
}

LoadedAPK对象使用来保存一个apk文件的信息,这个构造方法中会将使用的包名指定为"android",而framework-res.apk的包名正是"android"。因此,getSystemContext()方法返回的mSystemContext对象所对应的apk文件就是framework-res.apk。

那么回到attach()方法就好理解了,attach()返回中新创建的ContextImpl对象实际上是在复制mSystemContext对象,接下来创建的Application对象实际代表了framework-res.apk。因此,ActivityThread的systemMain()方法相当于创建了一个framework-res.apk的上下文环境。

2 通过createSystemContext()获取到mSystemContext之后,创建SystemServiceManager对象mSystemServiceManager,我们知道SystemServer主要是创建各种服务,而该对象就是主要负责管理各种系统Service的创建,启动和其他生命周期的;然后调用

 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

addService()是将SystemServiceManager对象保存SystemServer进程中的一个ArrayMap中。

public static <T> void addService(Class<T> type, T service) {
    synchronized (sLocalServiceObjects) {
        if (sLocalServiceObjects.containsKey(type)) {
            throw new IllegalStateException("Overriding service registration");
        }
        sLocalServiceObjects.put(type, service);
    }
}

SystemServer重要的Service

SystemServer进程是Android系统的核心之一,大部分Android提供的服务都在该进程中,SystemServer中运行的进程公共有六十多种,介绍下重要的几个service;

  • ActivityManagerService->ActivityManager
    ActivityManagerService是整个Android Framework框架中最为核心的一个服务,管理整个框架中任务,进程管理,Intent解析等的核心实现。虽然名为Activity的ManagerService,但是它管辖的范围,不只是Activity,还有其他三大组件,和他们所在的进程。也就是说用户应用程序的生命管理都是由ActivityManagerService负责的。
  • PackageManagerService -> PackageManager
    包括对软件包的解包,验证,安装以及升级等等,不能安装.so文件的问题,应该先从这块着手分析原因。
  • WindowManagerService -> WindowManager -> PhoneWindowManager
    和ActivityManagerService高度粘合;窗口管理,这里最核心的就是输入事件的分发和管理。

以上就是SystemServer进程的创建,初始化和主要Service的介绍,如有问题,请多指教,谢谢!

Android FrameWork的文章现在有很多,相关的书籍也有不少,都写的很通俗易懂,我写相关的文章主要是为了记录在学习FrameWork过程中的点滴。大家也可以阅读下面的文章
Android源码解析之(九)–>SystemServer进程启动流程

参考文档

刘超《深入解析Android5.0》第十章Android系统的核心之一 –SystemServer进程

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 12 SystemServer 的启动流程如下: 1. 引导加载:系统启动时,先加载引导程序,进行硬件初始化、内核加载等操作。 2. Zygote 进程启动:Zygote 是 Android 系统的一个特殊进程,负责孵化其他应用进程。Zygote 进程会预加载一些常用的类和资源,以加快应用的启动速度。 3. SystemServer 进程启动:Zygote 进程会 fork 出 SystemServer 进程,该进程是 Android 系统的核心服务进程。SystemServer 进程负责启动和管理系统级别的服务,例如 ActivityManagerService、PackageManagerService、WindowManagerService 等。 4. SystemServer 初始化:SystemServer 进程启动后,会进行一系列的初始化操作。首先会创建 Looper 线程,用于接收消息并处理各个服务的初始化工作。然后依次创建各个系统服务,并调用它们的启动方法。 5. 启动系统服务:SystemServer 进程会按照一定顺序启动各个系统服务。每个系统服务都有自己的初始化流程,例如 PackageManagerService 会加载应用程序列表、数据目录等;ActivityManagerService 会初始化进程间通信机制等。 6. 启动应用进程:在系统服务启动完成后,SystemServer 进程会通过 Zygote 孵化出其他应用进程。应用进程会根据 AndroidManifest.xml 的配置进行初始化,包括创建 Application、加载资源等。 总结来说,Android 12 SystemServer 的启动流程包括引导加载、Zygote 进程启动、SystemServer 进程启动、SystemServer 初始化、启动系统服务和启动应用进程等步骤。这些步骤都是为了在系统启动时提供必要的服务和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值