美文网首页
SystemServer启动

SystemServer启动

作者: nianxing | 来源:发表于2021-11-20 11:18 被阅读0次

    本文基于安卓6.0源码,对systemserver进程的启动与管理的基本过程进行介绍。
    从Zygote进程初始化ZygoteInit.main()中调用startSystemServer()fork出子进程开始。
    SystemServer负责启动和管理整个java framework,包含ActivityManager,WindowManager,PackageManager以及PowerManager等。

    在一号进程init(),解析init.rc文件,并启动其中的Zygote服务,会调用ZygoteInit.main()方法,在其中先fork出SystemServer进程,fork出进程之后根据pid分别处理子进程与父进程。在子进程中将复制过来的socket关闭(fork规则:读时共享,写时复制)。

    init完成之后,抛出ZygoteInit.MethodAndArgsCaller(m, argv)异常后,抓取该异常执行到caller.run()然后反射调用SysemServer.main()方法启动SystemServer。

    在SysemServer.main()中,会直接调用SystemServer.run()方法启动SystemServer。

    Start! GO

    1、SystemServer启动概览

    SystemServer.run()方法中会调用到SystemServer启动的全部方法,最重要的几点步骤总结如下:

    1. 准备主线程Looper
    2. 加载android_servers.so库
    3. 初始化系统上下文
    4. 启动80多种系统服务
    5. 进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再进行处理。
    SystemServer.java
        private void run() {
            //设置最早时间戳,不能早于1970年。安卓时间戳的计算是从1970年开始的。
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }
     
           //设置语言相关
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();
     
                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }
     
            //正式开始SystemServer进程的启动,Here we go!
          
            Slog.i(TAG, "Entered the Android system server!");
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
    ...
     
            //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
            BinderInternal.disableBackgroundScheduling(true);
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
     
            //1:准备主线程Looper
            Looper.prepareMainLooper();
     
            //2:加载android_servers.so库
            System.loadLibrary("android_servers");
     
            //检测上次关机过程是否失败,该方法可能不会返回
            performPendingShutdown();
     
            //3:初始化系统上下文
            createSystemContext();
     
            // 创建系统服务管理(mSystemServiceManager),并将该管理加入到本地服务(LocalServices)
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
     
            //4:启动服务
            //启动引导服务也可以说是关键服务,最重要的服务。包括AMS,PKMS,DisplayManagerService等。核心服务与其他服务会被这些服务所依赖,所以需要先启动这些引导服务。startBootstrapServices()
            //启动核心服务,包括WindowManagerService,InputManagerService等。
            //启动其他的服务,startOtherServices()
            try {
                startBootstrapServices();
                startCoreServices();
                startOtherServices();
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            }
    ...
     
            //5:进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再进行处理。
            Looper.loop();
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    2、初始化系统上下文

    SystemServer.createSystemContext()
    private void createSystemContext() {
            ActivityThread activityThread = ActivityThread.systemMain();
            mSystemContext = activityThread.getSystemContext();
    //设置一下系统主题
            mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
        }
    

    2.1 ActivityThread activityThread = ActivityThread.systemMain()

    ActivityThread.systemMain()
        public static ActivityThread systemMain() {
    //低内存上不开启硬件加速,因为会增加过多的开销。这里可以不必在意,关注系统上下文初始化过程即可。
            if (!ActivityManager.isHighEndGfx()) {
                HardwareRenderer.disable(true);
            } else {
                HardwareRenderer.enableForegroundTrimming();
            }
     
            ActivityThread thread = new ActivityThread();
    //这里thread.attach(true),ActivityThread的attach函数是任何进程创建过程中都会调用的。
    //需要注意的是,app创建时调用的是attach(false),进入attach()函数之后,会根据是否是系统进程判断,执行逻辑会大不相同。
            thread.attach(true);
            return thread;
        }
    

    下面看一下attach函数,这里仅需要了解即可。我会在application的启动过程中详细介绍attach流程。

    1. 创建mInstrumentation
    2. 创建appContenx
    3. 创建application
    ActivityThread.attach()
    private void attach(boolean system) {
            sCurrentActivityThread = this;
            mSystemThread = system;
            if (!system) {
     //如果是用户进程,这里会直接调用AMS的代理的attachApplication(mAppThread)。把自身的mApplicationThread类型的成员变量(mAppThread),直接传递过去。
     //这里还是关注系统进程的执行逻辑
            } else {
                // Don't set application object here -- if the system crashes,
                // we can't display an alert, we just want to die die die.
                android.ddm.DdmHandleAppName.setAppName("system_process",
                        UserHandle.myUserId());
                try {
    //1:先创建一个mInstrumentation,它是ActivityThread的成员,每一个ActicityThread对象都有一个mInstrumentation。
    //我的理解是,使用该类可以去控制和观察application及activity生命周期。
    //这里知道一下即可,不必要太关注。
                    mInstrumentation = new Instrumentation();
    //2:创建appContenx,ContextImpl类是Activity.java,ContextWrapper.java中方法的实现类。
    //比如startActivity(),start/bindService(),sendBroadcast()等方法都是在该类中实现的。
                    ContextImpl context = ContextImpl.createAppContext(
                            this, getSystemContext().mPackageInfo);
    //3:然后是makeApplication,即创建application。
    //每一个进程只有一个application,可以在makeApplication()中看到,如果application不为空,会直接返回,而不会新创建application。
    //这里暂时还不是特别明白,以后再深究。
    //在makeApplication()调用了 instrumentation.callApplicationOnCreate(app),这里调用了onCreate()实际上调用的application.onCreate(),以后再深究吧。
                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                    mInitialApplication.onCreate();
                } catch (Exception e) {
                    throw new RuntimeException(
                            "Unable to instantiate Application():" + e.toString(), e);
                }
            }
    ...
     }
    

    2.2 mSystemContext = activityThread.getSystemContext()

    创建系统上下文,简单的单例模式。

    ActivityThread.getSystemContext()
    //简单的单例模式,创建系统上下文   
    public ContextImpl getSystemContext() {
            synchronized (this) {
                if (mSystemContext == null) {
                    mSystemContext = ContextImpl.createSystemContext(this);
                }
                return mSystemContext;
            }
        }
    

    3、启动服务

    启动服务过程中,安卓将这些服务分为3类。

    • 第一类:startBootstrapServices(),启动系统关键服务。这些服务是安卓系统中最关键的服务,其他服务可能依赖于这些服务的创建,是开机启动中最紧急需要启动的服务。
    • 第二类 :startCoreServices(),启动核心服务。系统中的核心服务,缺少这些服务手机基本无法使用。
    • 第三类:startOtherServices(),启动其余的服务。除非必要,我们自己开发的普通系统服务都应该放在这里启动。

    在这些服务的最后,一定都会调用serviceManager.addService()方法,将这些服务注册到serviceManager中,等待调用。

    相关文章

      网友评论

          本文标题:SystemServer启动

          本文链接:https://www.haomeiwen.com/subject/tpbytrtx.html