该系列文章总纲链接:专题分纲目录 android 开机启动流程分析
这里因为整体的导图太大,因此截取一部分 ,方便大家看的清楚:
同时,下面的图是开机启动流程分析 持续迭代的效果,可放大观看。
说明:思维导图是基于之前文章不断迭代的,本章内容我们关注➕"启动SystemServer ->SS"部分即可
1 SS创建
1.1 SS fork进程
SystemServer的进程名实际上叫system_server(后简称为SS)。SS是由Zygote通过Zygote.forkSystemServer函数fork诞生出来的。forkSystemServer的实现(java部分)代码如下:
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { VM_HOOKS.preFork(); /** nativeForkSystemServer{java->native调用关联} ->com_android_internal_os_Zygote_nativeForkSystemServer//接下来关键分析该方法 */ int pid = nativeForkSystemServer( uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); VM_HOOKS.postForkCommon(); return pid; }native层对应实现方法com_android_internal_os_Zygote_nativeForkSystemServer,代码如下:
static jint com_android_internal_os_Zygote_nativeForkSystemServer(JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,jlong effectiveCapabilities) { //根据传递的参数,fork一个子进程 pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,debug_flags, rlimits,permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,NULL, NULL); if (pid > 0) { gSystemServerPid = pid; //保存system_server的进程id int status; if (waitpid(pid, &status, WNOHANG) == pid) { //函数退出前须先检查刚创建的子进程是否退出了 RuntimeAbort(env); //如果system_server退出了,Zygote直接干掉了自己 } } return pid; }继续分析ForkAndSpecializeCommon,实现如下:
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid,...) { uint64_t start = MsTime(); /** SetSigChldHandler ->sigaction(SIGCHLD, &sa, NULL);//设置信号处理函数sigchldHandler {该信号是子进程死亡的信号,进程死亡会执行对应的信号处理函数} -->sigchldHandler处理信号{ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { ... if (pid == gSystemServerPid) {//如果死去的子进程是SS,则Zygote把自己也杀死了 kill(getpid(), SIGKILL); } } } */ SetSigChldHandler(); ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler"); pid_t pid = fork(); if (pid == 0) {//子进程初始化操作 //对子进程要根据传入的参数做一些处理,例如设置进程名,设置各种id(用户id,组id等) ... } else if (pid > 0) { //父进程相关操作 ... } return pid;//注意,这里也意味着有两个返回值 }1.2 SystemServer创建过程
SS创建后,便和生父Zygote分开处理,它有了自己的历史使命。 startSystemServer中在子进程SS中最关键调用为handleSystemServerProcess来承担自己的职责。代码实现如下:
//startSystemServer->handleSystemServerProcess private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket();//因为当前已经不是运行在zygote进程里了,所以zygote里的那个监听socket就应该关闭了 // 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);//设置进程名为niceName,也就是"system_server" } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); } if (parsedArgs.invokeWith != null) { String[] args = parsedArgs.remainingArgs; if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); } //设置SS进程的一些参数 WrapperInit.execApplication(parsedArgs.invokeWith,parsedArgs.niceName, parsedArgs.targetSdkVersion,null, args); } else { ClassLoader cl = null; if (systemServerClasspath != null) { cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(cl); } //调用ZygoteInit函数 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } }SS走到RuntimeInit了,它的代码实现如下所示:
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { redirectLogStreams();//重定向Log输出流。 commonInit();//做一些常规初始化。{时区,网络,日志} nativeZygoteInit();//native层的初始化,关键点1 applicationInit(targetSdkVersion, argv, classLoader);//应用初始化,关键点2 }1.2.1 nativeZygoteInit的调用栈,代码实现如下:
/** nativeZygoteInit{java->native调用关联} ->com_android_internal_os_RuntimeInit_nativeZygoteInit -->gCurRuntime->onZygoteInit();//app_process的main函数中的runtime {gCurRuntime类型为AppRuntime,由于SS是从Zygote fork出来的,所以它拥有Zygote进程的gCurRuntime} {AppRuntime继承AndroidRuntime,初始化时会执行gCurRuntime = this;的操作,即gCurRuntime被设置为AndroidRuntime对象自己} */分析gCurRuntime->onZygoteInit()的实现(定要在App_main.cpp中)如下:
virtual void onZygoteInit() { //这些和Binder有关系 sp<ProcessState> proc = ProcessState::self(); proc->startThreadPool();/启动一个线程,用于Binder通信。 }SS调用zygoteInitNative后,将和Binder通信系统建立联系,这样SS就能够使用Binder了。 1.2.2 applicationInit的分析,代码实现如下:
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { nativeSetExitWithoutCleanup(true); VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args; args = new Arguments(argv); ...//异常处理 //这里注意:startClass名为"com.android.server.SystemServer" invokeStaticMain(args.startClass,args.startArgs, classLoader); }这里分析关键代码invokeStaticMain,实现如下:
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { //注意我们的参数,className为"com.android.server.SystemServer" Class<?> cl = Class.forName(className, true, classLoader); ...//异常处理 //找到com.android.server.SystemServer类的main函数,肯定有地方要调用它 Method m; m = cl.getMethod("main", new Class[] { String[].class }); 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 ZygoteInit.MethodAndArgsCaller(m, argv); }invokeStaticMain竟然抛出了一个异常,它是在ZygoteInit的main函数中截获。
代码如下(注意:我们所在的进程是system_server):
... //接着ZygoteInit中第5个关键点继续分析 ... if (startSystemServer) { //我们传入的参数满足if分支,这里是可能抛出异常的 startSystemServer(abiList, socketName);//该方法最后抛出一个异常MethodAndArgsCaller } ... } catch (MethodAndArgsCaller caller) { /** caller的run方法 mMethod.invoke(null, new Object[] { mArgs }); {mMethod为com.android.server.SystemServer的main函数} {抛出的这个异常最后会导致com.android.server.SystemServer类的main函数被调用} */ caller.run(); //关键点5,被截获,调用caller的run函数 } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; }说明:
父进程Zygote在fork动作后,会退出startSystemServer()函数,并走到runSelectLoop(),从而进入一种循环监听状态,每当AMS向它发出“启动新应用进程”的命令时,它又会fork一个子进程,并在子进程里抛出一个异常,这样还是会跳转到catch这里。fork出的SystemServer进程在跳转到catch语句后,会执行SystemServer类的main()函数,而其他情况下,fork出的应用进程在跳转的catch语句后,则会执行ActivityThread类的main()函数。这个ActivityThread对于应用程序而言非常重要为什么不在invokeStaticMain那里直接调用,而是采用这种抛异常的方式?这是因为:这个调用是在ZygoteInit.main中,相当于Native的main函数,即入口函数,位于堆栈的顶层。如果不采用抛异常的方式,而是在invokeStaticMain那里调用,则会浪费之前函数调用所占用的一些调用堆栈。这是从效率上来考虑的(由于是系统层的设计,一点点的效率都不可以忽视)整个过程目的:ZygoteInit分裂产生的SS,其实就是为了调用com.android.server.SystemServer的main函数。
2 SS启动
这里直接查看run的实现,代码如下:
//main->new SystemServer().run(); private void run() { ...// 检测时间设置 ...// 启动性能分析采样 ... // Within the system server, it is an error to access Environment paths without explicitly specifying a user. Environment.setUserRequired(true); // Ensure binder calls into the system always run at foreground priority. BinderInternal.disableBackgroundScheduling(true); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); ... Looper.prepareMainLooper(); //准备主线程循环 // Initialize native services. System.loadLibrary("android_servers"); //加载libandroid_servers.so,源码在framework/base/services/jni下。 nativeInit();//调用native函数,关键点1 ... performPendingShutdown();// Check whether we failed to shut down last time we tried.This call may not return. createSystemContext();//初始化系统上下文,关键点2 // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // 启动服务 try { startBootstrapServices();//启动BootStrap相关服务,关键点3 startCoreServices();//启动核心服务,关键点4 startOtherServices();//启动其他服务,关键点5 } catch (Throwable ex) { /// M: RecoveryManagerService @{ if (mRecoveryManagerService != null && ex instanceof RuntimeException) { mRecoveryManagerService.handleException((RuntimeException)ex, true); } } ... addBootEvent(new String("Android:SysServerInit_END")); // Loop forever. Looper.loop();// 启动线程循环,等待消息处理 throw new RuntimeException("Main thread loop unexpectedly exited");//不应该执行到这里 }2.1 native_init调用栈如下:
/** nativeInit{java->native调用关联} ->android_server_SystemServer_nativeInit -->property_get("system_init.startsensorservice", propBuf, "1"); -->if (strcmp(propBuf, "1") == 0){SensorService::instantiate();} {通过属性确定SensorService是否启动} */2.2 关注createSystemContext,代码实现如下:
private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }这里主要就是初始化mSystemContext成员变量。2.3 启动各种各样的服务 2.3.1 startBootstrapServices();//引导服务,使系统可以正常工作的必要服务,这些服务具有复杂的相互依赖性
private void startBootstrapServices() { //服务必须提前加载的原因 //installd完成启动它才有一个机会用适当的方法创建关键的目录,如数据/用户权限。 Installer installer = mSystemServiceManager.startService(Installer.class); //AMS是核心显示相关 mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); //PowerMS很多服务需要使用它,被native daemon监听并很快处理binder回调 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); //AMS关联PowerMS mActivityManagerService.initPowerManagement(); //为PackageMS初始化准备 mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); // Only run "core" apps if we're encrypting the device. String cryptState = SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } else if (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; } //PackageMS启动初始化 mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); //用attribute cache来初始化packages的cache resources AttributeCache.init(mSystemContext); //为系统进程设置应用程序实例且启动 mActivityManagerService.setSystemProcess(); }2.3.2 startCoreServices(); //核心服务,启动一些不在引导过程中的一些基本服务。
private void startCoreServices() { // Manages LEDs and display backlight. mSystemServiceManager.startService(LightsService.class); // Tracks the battery level. Requires LightService. mSystemServiceManager.startService(BatteryService.class); // Tracks application usage stats. mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); // Update after UsageStatsService is available, needed before performBootDexOpt. mPackageManagerService.getUsageStatsIfNoPackageUsageInfo(); // Tracks whether the updatable WebView is in a ready state and watches for update installs. mSystemServiceManager.startService(WebViewUpdateService.class); }2.3.3 startOtherServices(); //其他服务,一般添加服务都在这里添加{所有其他的java系统服务都在这里启动}
private void startOtherServices() { final Context context = mSystemContext; AccountManagerService accountManager = null; ... AudioService audioService = null; MmsServiceBroker mmsService = null; ... try { Slog.i(TAG, "Reading configuration..."); SystemConfig.getInstance(); Slog.i(TAG, "Scheduling Policy"); ServiceManager.addService("scheduling_policy", new SchedulingPolicyService()); mSystemServiceManager.startService(TelecomLoaderService.class); ... try { wm.displayReady(); } catch (Throwable e) { reportWtf("making display ready", e); } ... mActivityManagerService.systemReady(new Runnable() { @Override public void run() { Slog.i(TAG, "Making services ready"); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); ... try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } ... } }); }2.4 总结 在这个run方法中,主要完成三件事情:
创建system context和system service manager启动一些系统服务进入主线程消息循环。2.5 SS整体总结
Zygote调用startSystemServer创建system_server进程 SS调用handleSystemServerProcess完成自己的使命 handleSystemServerProcess抛出异常,最终调用com.android.server.SystemServer的main函数 main加载libandroid_server.so并调用native_init方法 在后面的3个关键方法中,启动一些系统服务 startBootstrapServices(); startCoreServices(); startOtherServices(); 进入消息循环,等待请求说明:启动系统各项服务,Java世界的核心Service都在这里启动,所以它非常重要。