Android 系统启动流程(三)SystemServer启动流程

前言

Android 系统启动流程(二) zygote启动流程这片文章中,我们学习了Zygote的启动过程,并且知道 Zygote创建并启动了SystemServer,这篇文章我们来学习下SystemServer的启动过程。

1 Zygote启动SystemServer

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

    private static Runnable forkSystemServer(String abiList, String socketName,
           ZygoteServer zygoteServer) {
       long capabilities = posixCapabilitiesAsBits(
           OsConstants.CAP_IPC_LOCK,
           OsConstants.CAP_KILL,
           OsConstants.CAP_NET_ADMIN,
           OsConstants.CAP_NET_BIND_SERVICE,
           OsConstants.CAP_NET_BROADCAST,
           OsConstants.CAP_NET_RAW,
           OsConstants.CAP_SYS_MODULE,
           OsConstants.CAP_SYS_NICE,
           OsConstants.CAP_SYS_PTRACE,
           OsConstants.CAP_SYS_TIME,
           OsConstants.CAP_SYS_TTY_CONFIG,
           OsConstants.CAP_WAKE_ALARM,
           OsConstants.CAP_BLOCK_SUSPEND
       );
       ...

       /* Hardcoded command line to start the system server */
       //设置参数
       String args[] = {
           "--setuid=1000",//uid,pid的设置
           "--setgid=1000",
           /// M: [Wi-Fi Hotspot Manager] system_server add dhcp (1014) group to access
           /// "/data/misc/dhcp/dnsmasq.leases"
           "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1014,1018,1021,1023," +
                       "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
           "--capabilities=" + capabilities + "," + capabilities,
           "--nice-name=system_server",//进程名
           "--runtime-args",
           "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
           "com.android.server.SystemServer",//启动类
       };
       ZygoteConnection.Arguments parsedArgs = null;

       int pid;

       try {
           parsedArgs = new ZygoteConnection.Arguments(args);//将args封装成Arguments
           ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
           ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

           boolean profileSystemServer = SystemProperties.getBoolean(
                   "dalvik.vm.profilesystemserver", false);
           if (profileSystemServer) {
               parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
           }

           /* Request to fork the system server process */
           //1 fork子进程,用于运行SystemServer
           pid = Zygote.forkSystemServer(
                   parsedArgs.uid, parsedArgs.gid,
                   parsedArgs.gids,
                   parsedArgs.runtimeFlags,
                   null,
                   parsedArgs.permittedCapabilities,
                   parsedArgs.effectiveCapabilities);
       } catch (IllegalArgumentException ex) {
           throw new RuntimeException(ex);
       }

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

           zygoteServer.closeServerSocket();//关闭从Zygote复制过来的Socket
           return handleSystemServerProcess(parsedArgs);//2 完成system_server进程剩余的工作
       }

       return null;
   }

在注释1处调用forkSystemServer来fork子进程,pid = 0说明进入子进程,然后在注释2处调用handleSystemServerProcess来完成system_server进程剩余的工作,我们来看下handleSystemServerProcess做了上面工作。

2 启动SystemServer

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
       // 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);//设置进程名:system_server
       }

       final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
       if (systemServerClasspath != null) {
           performSystemServerDexOpt(systemServerClasspath);//执行dex优化
           // Capturing profiles is only supported for debug or eng builds since selinux normally
           // prevents it.
           boolean profileSystemServer = SystemProperties.getBoolean(
                   "dalvik.vm.profilesystemserver", false);
           if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
               try {
                   prepareSystemServerProfile(systemServerClasspath);
               } catch (Exception e) {
                   Log.wtf(TAG, "Failed to set up system server profile", e);
               }
           }
       }

       if (parsedArgs.invokeWith != null) {
           String[] args = parsedArgs.remainingArgs;
           // If we have a non-null system server class path, we'll have to duplicate the
           // existing arguments and append the classpath to it. ART will handle the classpath
           // correctly when we exec a new process.
           if (systemServerClasspath != null) {
               String[] amendedArgs = new String[args.length + 2];
               amendedArgs[0] = "-cp";
               amendedArgs[1] = systemServerClasspath;
               System.arraycopy(args, 0, amendedArgs, 2, args.length);
               args = amendedArgs;
           }

           WrapperInit.execApplication(parsedArgs.invokeWith,
                   parsedArgs.niceName, parsedArgs.targetSdkVersion,
                   VMRuntime.getCurrentInstructionSet(), null, args);

           throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
       } else {
           ClassLoader cl = null;
           if (systemServerClasspath != null) {
               cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

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

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

       /* should never reach here */
   }

注释1处调用ZygoteInit的zygoteInit,下面来看下它干了什么。

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

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

       RuntimeInit.commonInit();//1
       ZygoteInit.nativeZygoteInit();//2
       return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);//3
   }
  • 注释1:通用初始化
  • 注释2:Zygote初始化
  • 注释3:应用初始化
    下面我们来看下他们分别做了什么
2.1 RuntimeInit.commonInit

frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

  protected static final void commonInit() {
        if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");

        /*
         * set handlers; these apply to all threads in the VM. Apps can replace
         * the default handler, but not the pre handler.
         */
         //设置未捕获异常处理方法
        LoggingHandler loggingHandler = new LoggingHandler();
        Thread.setUncaughtExceptionPreHandler(loggingHandler);
        Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));

        /*
         * Install a TimezoneGetter subclass for ZoneInfo.db
         */
         //设置时区
        TimezoneGetter.setInstance(new TimezoneGetter() {
            @Override
            public String getId() {
                return SystemProperties.get("persist.sys.timezone");
            }
        });
        TimeZone.setDefault(null);

        /*
         * Sets handler for java.util.logging to use Android log facilities.
         * The odd "new instance-and-then-throw-away" is a mirror of how
         * the "java.util.logging.config.class" system property works. We
         * can't use the system property here since the logger has almost
         * certainly already been initialized.
         */
        LogManager.getLogManager().reset();
        new AndroidConfig();

        /*
         * Sets the default HTTP User-Agent used by HttpURLConnection.
         */
         //设置UserAgent
        String userAgent = getDefaultUserAgent();
        System.setProperty("http.agent", userAgent);

        /*
         * Wire socket tagging to traffic stats.
         */
        NetworkManagementSocketTagger.install();

        /*
         * If we're running in an emulator launched with "-trace", put the
         * VM into emulator trace profiling mode so that the user can hit
         * F9/F10 at any time to capture traces.  This has performance
         * consequences, so it's not something you want to do always.
         */
        String trace = SystemProperties.get("ro.kernel.android.tracing");
        if (trace.equals("1")) {
            Slog.i(TAG, "NOTE: emulator trace profiling enabled");
            Debug.enableEmulatorTraceOutput();
        }

        initialized = true;
    }
2.2 ZygoteInit.nativeZygoteInit

nativeZygoteInit()方法在AndroidRuntime.cpp中,进行了jni映射,对应下面的方法

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
    gCurRuntime->onZygoteInit();
}

frameworks\base\cmds\app_process\app_main.cpp

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();//1
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();//2
    }
  • 注释1 :采用单列模式创建ProcessState对象并打开/dev/binder驱动设备,然后调用mmap分配一块内存,并映射内存起始地址。
  • 注释2:创建一个新的binder线程,不断进行talkWithDriver
    通过ZygoteInit.nativeZygoteInit的初始化,SystemServer可以通过Binder与其他进程进行IPC通信。
2.3 RuntimeInit.applicationInit

frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        ...

        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

applicationInit主要调用了findStaticMain

    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);//1
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });//2
        } 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);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        return new MethodAndArgsCaller(m, argv);//3
    }
  • 注释1:通过反射得到SystemServer类
  • 注释2:通过反射得到SystemServer类的main方法
  • 注释3:返回一个MethodAndArgsCaller的Runnable的对象

通过上边一系列的工作,返回一个Runnable对象,然后我们返回到ZygoteInit的main方法

 public static void main(String argv[]) {
        ...

            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);//1

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();//2
                    return;
                }
            }

            ...
    }
  • 注释1:forkSystemServer我们得到了一个包含SystemServer类main方法的MethodAndArgsCaller对象
  • 注释2:然后调用MethodAndArgsCaller类的run方法来启动SystemServer。
   static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });//1
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }
  • 注释1:通过反射调用SystemServer的main方法

frameworks\base\services\java\com\android\server\SystemServer.java

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

到此,SystemServer已经启动起来了,下面我们来看下SystemServer的启动过程

3 SystemServer的启动过程

frameworks\base\services\java\com\android\server\SystemServer.java

 private void run() {
        try {
            ...
            //将当前线程初始化为looper,将其标记为应用程序的主循环
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            // Initialize native services.
            System.loadLibrary("android_servers");//1

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            //初始化系统上下文
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();//3
            startCoreServices();//4
            startOtherServices();//5
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        ....
        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  • 注释1:加载libandroid_servers.so
  • 注释2:创建SystemServiceManager,对系统服务的声明周期进行管理
  • 注释3:启动引导服务(AMS,PowerManagerService,LightsService,PackageManagerService…)
  • 注释4:启动核心服务(BatteryService,UsageStatsService,WebViewUpdateService)
  • 注释5:启动其他服务(CameraService,InputManagerService,WindowManagerService,NotificationManagerService,AudioService …)
    可见,系统将服务分成了3大类,为什么要分批启动呢?笔者认为应该是为了解决各个服务之间的依赖。
3.1 SystemUI和Launcher的启动

SystemServer启动完各种服务之后会调用mActivityManagerService.systemReady

        mActivityManagerService.systemReady(new Runnable() {
            public void run() {
            traceBeginAndSlog("StartSystemUI");
            try {
                startSystemUi(context, windowManagerF);//启动SystemUI
            } catch (Throwable e) {
                reportWtf("starting System UI", e);
            }
            traceEnd();
              ...
            }
        });
        

---
    static final void startSystemUi(Context context, WindowManagerService windowManager) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

然后回调AMS.systemReady来启动Launcher

 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
            ...
            startHomeActivityLocked(currentUserId, "systemReady");//启动Launcher

            ...
    }

到此为止,我们的系统已经启动起来了。

总结

通过分析,我们了解到SystemSerer加载了android_servers.so,创建系统上下文,然后分批启动各种服务,启动完成之后回调AMS.systemReady来启动SystemUI跟Launcher,这样我们的系统就启动完成了。

欢迎关注我的微信公众号
欢迎关注我的公众号[Gee丶kk]一起探讨技术

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值