源码分析Android SystemServer进程的启动过程
2015-10-30 18:31
776 查看
最近复习了柯元旦老师的《Android内核剖析》,获益良多。所以想从自己的钻研出发,走一遍柯老师走过的路。我看的《Android内核剖析》版本是基于Android2.3系统来写的,因为我尝试从Android5.1系统再钻研一遍书籍中所钻研过的知识点。
本文将尝试从源码分析SystemServer进程的启动过程,Ams,Wms及其他常用到的服务的创建,以及打开第三方应用的启动过程。
一、SystemServer进程的启动
SystemServer听名字就知道是个非常重要的进程,它是Android Framework启动后fork的第一个进程,可见其重要性。那么该进程在跑什么东西呢?主要是一些系统服务,例如我们常听说的Ams(ActivityManagerService)和Wms(WindowManagerService)。
SystemServer的启动入口在ZygoteInit.java的main函数中。ZygoteInit是Zygote进程加载的第一个类,Zygote进程则是所有Apk应用进程的父进程,所有应用进程都是由Zygote进程fork出来。
从源码开始着手,我们只关心SystemServer相关的部分,ZygoteInit.java:
先看看main函数的参数,它的参数来自启动Zygote的命令,该命令在于系统根目录下的init.rc文件中,其中有一行是:
该行的意思是调用/system/bin/下的app_process命令(或工具),并且后面一串就是其主要参数。
该命令的源码在/frameworks/base/cmds/app_process/app_main.cpp里,我们跟进去看看主要部分:
看上面标注①的地方:如果有参数是”–start-system-server”,那么变量startSystemServer被置为true,从我们调用的命令来看,这么为true;
标注②:如果startSystemServer为true,那么变量args将添加”start-system-server”这个字符串。我们从变量名args可以猜测到这个变量是保存一些启动参数的。
标注③:毫无疑问这里会启动”com.android.internal.os.ZygoteInit”这个类并且带有参数args,如果一来就会辗转到ZygoteInit的main函数里,并且带有args的参数。
OK,终于明白ZygoteInit的main函数的参数有什么东东,接下来回到该类的main方法里:
标注①:正如刚才分析的,这里的参数是含有”start-system-server”这个字符串,所以此处startSystemServer变量被置为true;
标注②:调用接口startSystemServer();
终于看到启动SystemServer的地方了:
标注①:为SystemServer创建一些启动参数,注意这个参数,后面启动会用到。并且从参数可以知道,SystemServer的uid是1000,gid是1000还有一些相关信息都被硬编码的方式编写在此。(一般情况每一个apk应用都有唯一一个uid,用于区分,系统服务如Ams也会根据uid来判断应用的权限,一般uid=1000及其他一些系统的uid程序拥有很多系统权限,uid=0代表root用户)
标注②:重头戏来了!调用Zygote.forkSystemServer()接口fork一个SystemServer进程。fork是linux系统创建子进程的重要方法,其作用是复制当前进程,创建一个新的进程,但是其进程id不相同。当该方法返回值等于0时,代表是创建的新进程。
跟踪进去Zygote.forkSystemServer()接口,发现其调用了JNI的native方法,所以不跟进去,大概流程就是创建了一个新的进程。
标注③:正如上面所说,返回值等于0代表是创建了新的进程,也就是子进程,此时将会调用handleSystemServerProcess()方法去完成SystemServer的创建。
再跟进去该方法:
标注①:此处会调用WrapperInit.execApplication()方法,不断跟踪进去,会发现其最终调用的代码在于RuntimeInit类中:
RuntimeInit.java:
该方法的作用是反射调用你要创建的类的main方法。还记得上面创建SystemServer时有创建一堆参数,其最后一个参数是”com.android.server.SystemServer”。没错这个参数辗转最后会作为RuntimeInit.invokeStaticMain()方法的参数,所以这里会反射”com.android.server.SystemServer”该类,并执行其main函数,也就是创建了SystemServer进程后,执行其SystemServer类的main函数。
至此,SystemServer进程的启动过程已大致分析完成。
二、创建Ams、Wms等主要系统服务
这部分源码相对比较简单,主要就是SystemServer中调用的接口。
继续上部分的代码,这里会进入SystemServer的main函数:
标注①:准备主线程(也就是正在运行的线程)的Looper;
标注②:native调用,该方法的注释是Called to initialize native system services.
标注③:创建SystemServer的Context,后面继续分析;
标注④:创建SystemServiceManager,其作用就是创建并管理系统服务的生命周期;
标注⑤:
startBootstrapServices();
startCoreServices();
startOtherServices();
连续调用了三个接口,这三个接口正是创建了我们常见的各种系统服务,后面继续分析;
标注⑥:Looper开始循环,等待消息执行。
我们看看SystemServer的Context创建过程:
调用了ActivityThread.systemMain():
从这里可以看出SystemServer与普通Apk程序的创建还是很不相同,SystemServer的ActivityThread 是通过ActivityThread 的静态方法systemMain()创建,做了一些简单处理如设置无硬件加速等。不过同样的,其最终还是会调用attach方法,不同的是,普通apk程序调用的是attch(false),那么创建过程肯定也会大不一样。这里就不分析了,继续代码。
mSystemContext = activityThread.getSystemContext()会调用getSystemContext方法,然后里面又会调用ContextImpl.createSystemContext的方法:
对比创建Activity的Context,发现会有一些不同:
其不同性,这里不分析,至此SystemServer的Context已经创建好。
回到SystemServer.main()最重要的部分,创建系统服务,跟踪分析其三连调用
startBootstrapServices();
startCoreServices();
startOtherServices();:
其实就是创建并用SystemServiceManager或者ServiceManager管理着这些服务。注意,以前是没有SystemServiceManager,全部服务都是由ServiceManager进行管理的,官方这样修改的意图是什么还需要后续去研究。
上面的代码可以看到我们经常通过Context.getSystemService常用的一些Manager都这里创建了。
至此该部分的研究暂一段落。
三、普通Apk应用程序的启动过程
请看下一篇《源码分析Android 应用进程的启动过程》
本文将尝试从源码分析SystemServer进程的启动过程,Ams,Wms及其他常用到的服务的创建,以及打开第三方应用的启动过程。
一、SystemServer进程的启动
SystemServer听名字就知道是个非常重要的进程,它是Android Framework启动后fork的第一个进程,可见其重要性。那么该进程在跑什么东西呢?主要是一些系统服务,例如我们常听说的Ams(ActivityManagerService)和Wms(WindowManagerService)。
SystemServer的启动入口在ZygoteInit.java的main函数中。ZygoteInit是Zygote进程加载的第一个类,Zygote进程则是所有Apk应用进程的父进程,所有应用进程都是由Zygote进程fork出来。
从源码开始着手,我们只关心SystemServer相关的部分,ZygoteInit.java:
public static void main(String argv[]) { try { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; ① } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } ... if (startSystemServer) { startSystemServer(abiList, socketName); ② } ... } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } }
先看看main函数的参数,它的参数来自启动Zygote的命令,该命令在于系统根目录下的init.rc文件中,其中有一行是:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote -- start-system-server
该行的意思是调用/system/bin/下的app_process命令(或工具),并且后面一串就是其主要参数。
该命令的源码在/frameworks/base/cmds/app_process/app_main.cpp里,我们跟进去看看主要部分:
int main(int argc, char* const argv[]) { ... // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // Skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; ① } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } Vector<String8> args; if (!className.isEmpty()) { // We're not in zygote mode, the only argument we need to pass // to RuntimeInit is the application argument. // // The Remainder of args get passed to startup class main(). Make // copies of them before we overwrite them with the process name. args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i); } else { // We're in zygote mode. maybeCreateDalvikCache(); if (startSystemServer) { args.add(String8("start-system-server")); ② } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); // In zygote mode, pass all remaining arguments to the zygote // main() method. for (; i < argc; ++i) { args.add(String8(argv[i])); } } if (!niceName.isEmpty()) { runtime.setArgv0(niceName.string()); set_process_name(niceName.string()); } if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", args); ③ } else if (className) { runtime.start("com.android.internal.os.RuntimeInit", args); } else { fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); return 10; } }
看上面标注①的地方:如果有参数是”–start-system-server”,那么变量startSystemServer被置为true,从我们调用的命令来看,这么为true;
标注②:如果startSystemServer为true,那么变量args将添加”start-system-server”这个字符串。我们从变量名args可以猜测到这个变量是保存一些启动参数的。
标注③:毫无疑问这里会启动”com.android.internal.os.ZygoteInit”这个类并且带有参数args,如果一来就会辗转到ZygoteInit的main函数里,并且带有args的参数。
OK,终于明白ZygoteInit的main函数的参数有什么东东,接下来回到该类的main方法里:
public static void main(String argv[]) { try { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; ① } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } ... if (startSystemServer) { startSystemServer(abiList, socketName); ② } ... } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } }
标注①:正如刚才分析的,这里的参数是含有”start-system-server”这个字符串,所以此处startSystemServer变量被置为true;
标注②:调用接口startSystemServer();
终于看到启动SystemServer的地方了:
/** * Prepare the arguments and fork for the system server process. */ private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ... /* 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,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); /* 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); } handleSystemServerProcess(parsedArgs); ③ } return true; }
标注①:为SystemServer创建一些启动参数,注意这个参数,后面启动会用到。并且从参数可以知道,SystemServer的uid是1000,gid是1000还有一些相关信息都被硬编码的方式编写在此。(一般情况每一个apk应用都有唯一一个uid,用于区分,系统服务如Ams也会根据uid来判断应用的权限,一般uid=1000及其他一些系统的uid程序拥有很多系统权限,uid=0代表root用户)
标注②:重头戏来了!调用Zygote.forkSystemServer()接口fork一个SystemServer进程。fork是linux系统创建子进程的重要方法,其作用是复制当前进程,创建一个新的进程,但是其进程id不相同。当该方法返回值等于0时,代表是创建的新进程。
跟踪进去Zygote.forkSystemServer()接口,发现其调用了JNI的native方法,所以不跟进去,大概流程就是创建了一个新的进程。
标注③:正如上面所说,返回值等于0代表是创建了新的进程,也就是子进程,此时将会调用handleSystemServerProcess()方法去完成SystemServer的创建。
再跟进去该方法:
/** * Finish remaining work for the newly forked system server process. */ private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { ... final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); } 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(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); } WrapperInit.execApplication(parsedArgs.invokeWith, ① parsedArgs.niceName, parsedArgs.targetSdkVersion, null, args); } else { ... } /* should never reach here */ }
标注①:此处会调用WrapperInit.execApplication()方法,不断跟踪进去,会发现其最终调用的代码在于RuntimeInit类中:
RuntimeInit.java:
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; try { cl = Class.forName(className, true, classLoader); } 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 }); } 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. */ throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
该方法的作用是反射调用你要创建的类的main方法。还记得上面创建SystemServer时有创建一堆参数,其最后一个参数是”com.android.server.SystemServer”。没错这个参数辗转最后会作为RuntimeInit.invokeStaticMain()方法的参数,所以这里会反射”com.android.server.SystemServer”该类,并执行其main函数,也就是创建了SystemServer进程后,执行其SystemServer类的main函数。
至此,SystemServer进程的启动过程已大致分析完成。
二、创建Ams、Wms等主要系统服务
这部分源码相对比较简单,主要就是SystemServer中调用的接口。
继续上部分的代码,这里会进入SystemServer的main函数:
/** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } public SystemServer() { // Check for factory test mode. mFactoryTestMode = FactoryTest.getMode(); } private void run() { // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it shortly. if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // Here we go! Slog.i(TAG, "Entered the Android system server!"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system // property so that it is in sync. We can't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 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(); // 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); // 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); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); ① // Initialize native services. System.loadLibrary("android_servers"); nativeInit(); ② // 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); ④ LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Start services. try { startBootstrapServices(); ⑤ startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } // For debug builds, log event loop stalls to dropbox for analysis. if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } // Loop forever. Looper.loop(); ⑥ throw new RuntimeException("Main thread loop unexpectedly exited"); }
标注①:准备主线程(也就是正在运行的线程)的Looper;
标注②:native调用,该方法的注释是Called to initialize native system services.
标注③:创建SystemServer的Context,后面继续分析;
标注④:创建SystemServiceManager,其作用就是创建并管理系统服务的生命周期;
标注⑤:
startBootstrapServices();
startCoreServices();
startOtherServices();
连续调用了三个接口,这三个接口正是创建了我们常见的各种系统服务,后面继续分析;
标注⑥:Looper开始循环,等待消息执行。
我们看看SystemServer的Context创建过程:
private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }
调用了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. if (!ActivityManager.isHighEndGfx()) { HardwareRenderer.disable(true); } else { HardwareRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true); return thread; }
从这里可以看出SystemServer与普通Apk程序的创建还是很不相同,SystemServer的ActivityThread 是通过ActivityThread 的静态方法systemMain()创建,做了一些简单处理如设置无硬件加速等。不过同样的,其最终还是会调用attach方法,不同的是,普通apk程序调用的是attch(false),那么创建过程肯定也会大不一样。这里就不分析了,继续代码。
mSystemContext = activityThread.getSystemContext()会调用getSystemContext方法,然后里面又会调用ContextImpl.createSystemContext的方法:
static ContextImpl createSystemContext(ActivityThread mainThread) { LoadedApk packageInfo = new LoadedApk(mainThread); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, false, null, null); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY)); return context; }
对比创建Activity的Context,发现会有一些不同:
static ContextImpl createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, IBinder activityToken) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); if (activityToken == null) throw new IllegalArgumentException("activityInfo"); return new ContextImpl(null, mainThread, packageInfo, activityToken, null, false, null, null); }
其不同性,这里不分析,至此SystemServer的Context已经创建好。
回到SystemServer.main()最重要的部分,创建系统服务,跟踪分析其三连调用
startBootstrapServices();
startCoreServices();
startOtherServices();:
/** * Starts the small tangle of critical services that are needed to get * the system off the ground. These services have complex mutual dependencies * which is why we initialize them all in one place here. Unless your service * is also entwined in these dependencies, it should be initialized in one of * the other functions. */ private void startBootstrapServices() { // Wait for installd to finish starting up so that it has a chance to // create critical directories such as /data/user with the appropriate // permissions. We need this to complete before we initialize other services. Installer installer = mSystemServiceManager.startService(Installer.class); // Activity manager runs the show. mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); // Power manager needs to be started early because other services need it. // Native daemons may be watching for it to be registered so it must be ready // to handle incoming binder calls immediately (including being able to verify // the permissions for those calls). mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // Now that the power manager has been started, let the activity manager // initialize power management features. mActivityManagerService.initPowerManagement(); // Display manager is needed to provide display metrics before package manager // starts up. mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); // We need the default display before we can initialize the package manager. 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; } // Start the package manager. Slog.i(TAG, "Package Manager"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); Slog.i(TAG, "User Service"); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); // Initialize attribute cache used to cache resources from packages. AttributeCache.init(mSystemContext); // Set up the Application instance for the system process and get started. mActivityManagerService.setSystemProcess(); } /** * Starts some essential services that are not tangled up in the bootstrap process. */ 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); } /** * Starts a miscellaneous grab bag of stuff that has yet to be refactored * and organized. */ private void startOtherServices() { final Context context = mSystemContext; AccountManagerService accountManager = null; ContentService contentService = null; VibratorService vibrator = null; IAlarmManager alarm = null; MountService mountService = null; NetworkManagementService networkManagement = null; NetworkStatsService networkStats = null; NetworkPolicyManagerService networkPolicy = null; ConnectivityService connectivity = null; NetworkScoreService networkScore = null; NsdService serviceDiscovery= null; WindowManagerService wm = null; BluetoothManagerService bluetooth = null; UsbService usb = null; SerialService serial = null; NetworkTimeUpdateService networkTimeUpdater = null; CommonTimeManagementService commonTimeMgmtService = null; InputManagerService inputManager = null; TelephonyRegistry telephonyRegistry = null; ConsumerIrService consumerIr = null; AudioService audioService = null; MmsServiceBroker mmsService = null; ... }
其实就是创建并用SystemServiceManager或者ServiceManager管理着这些服务。注意,以前是没有SystemServiceManager,全部服务都是由ServiceManager进行管理的,官方这样修改的意图是什么还需要后续去研究。
上面的代码可以看到我们经常通过Context.getSystemService常用的一些Manager都这里创建了。
至此该部分的研究暂一段落。
三、普通Apk应用程序的启动过程
请看下一篇《源码分析Android 应用进程的启动过程》
相关文章推荐
- Android Studio征服记——软件问题记录
- 删除Android工程中冗余资源
- 动态改变ToolBar内菜单选项
- Android启动过程以及各个镜像的关系——推荐android初学者必看的一篇文章!
- android照相、相册获取图片剪裁部分手机异常的解决方法
- android调用摄像头拍照,从相册中选择照片并裁剪
- 新建android projec activityt的时候遇到这个错误
- Android SDK开发包下载地址
- 基于openfire+smack开发Android即时聊天应用[三]-账号信息、添加好友、JID理解等
- 可以添加Footer和Header的GridView
- Android如何防止apk程序被反编译
- Android APK反编译就这么简单 详解(附图)
- 关于Android下FloatMath问题
- Android自定义折线图
- android Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)
- AndroidStudio安装详解
- android代码混淆
- android js和webview交互
- android sdk版本版本与ADT版本不兼容的处理办法
- Android Studio如何在项目中使用jni以及OpenCV库