美文网首页
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