Android源码学习--SystemServer进程
SystemServer进程在Android中的角色
SystemServer进程是Android系统的核心之一,大部分Android提供的服务都运行在这个进程里,如AMS,PMS,等六十多种服务。我们都知道Android的应用进程没有权限直接访问设备的底层资源,只能通过SystemServer中的服务代理访问,这样做的目的是为了防止应用进程对系统造成破坏。
SystemServer进程的创建过程
一、 创建SystemServer进程
ZygoteInit类的main()方法里调用startSystemServer()方法来启动SystemServer。
//位于ZygoteInit.javaprivate static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ... // 准备启动参数 String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; ... int pid; try { ... pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } // 进入子进程system_server if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } // 完成system_server进程剩余的工作 handleSystemServerProcess(parsedArgs); } return true; }
在startSystemServer()方法中,主要做了3件事:
1.为SystemServer准备启动参数。
SystemServer进程的uid和gid都被指定为1000。SystemServer进程的名字是system_server,其执行类是com.android.server.SystemServer。
2.调用Zygote类的forkSystemServer()来fork出SystemServer子进程。
forkSystemServer()方法最终会调用native层的nativeForkSystemServer()函数,最终调用ForkAndSpecializeCommon函数来执行实际的fork操作。
在native层调用完forkAndSpecializeCommon()函数后,如果启动的是SystemServer,Zygote会检查SystemServer是否启动成功,如果失败,Zygote进程会让进程自己退出,重启zygote进程。
//位于com_android_internal_os_Zygote.cppstatic 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_DEFAULT, NULL, NULL, true, NULL, NULL, NULL); if (pid > 0) { // zygote进程检测子进程是否创建 gSystemServerPid = pid; int status; if (waitpid(pid, &status, WNOHANG) == pid) { // system_server进程死亡后,重启zygote进程 RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); } } return pid;}
在ForkAndSpecializeCommon()函数中将调用fork()函数来创建子进程之前还调用了SetSigChldHandler函数设置处理SIGCHLD信号的函数SigChldHandler()。
static void SigChldHandler(int /*signal_number*/) { pid_t pid; ... while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { ... if (pid == gSystemServerPid) { ALOGE("Exit zygote because system server (%d) has terminated", pid); kill(getpid(), SIGKILL); // 如果死亡的是SystemServer进程,zygote将退出 } } ...}
SigChldHandler函数接收到子进程死亡的信号后,除了调用waitpid()来防止子进程变“僵尸”外,还会判断死亡的子进程是否是SystemServer进程,如果是,Zygote进程会“自杀”,这样将导致Init进程杀死所有用户进程并重启Zygote。整个手机相当于重启了一扁,从而达到系统“软重启”的目的。
3.在fork出SystemServer进程后,在fork出的进程中调用handleSystemServerProcess()来初始化SystemServer进程。
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { // 关闭父进程zygote复制而来的Socket closeServerSocket(); // 接SystemServer进程的umask设为0077(S_IRWXG|S_IRWXO), // 这样SystemServer创建的文件的属性就是0077,只有SystemServer进程可以访问。 Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { // 设置当前进程名为 "system_server" Process.setArgV0(parsedArgs.niceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { // 执行dex优化操作 performSystemServerDexOpt(systemServerClasspath); } if (parsedArgs.invokeWith != null) {// 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); } // 启动应用进程 WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); } else { ClassLoader cl = null; if (systemServerClasspath != null) { //创建类加载器,并赋予当前线程 cl = createSystemServerClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } }
因为参数invokeWith通常为null,所以会调用RuntimeInit.zygoteInit()方法。在zygoteInit()方法中,它最终会以抛出MethodAndArgsCaller异常的方式返回,实现真正调用SystemServer类的main()方法。
二、SystemServer的初始化
SystemServer是一个java类,其main()方法中调用了对象的run()方法。
public static void main(String[] args) { //先初始化SystemServer对象,再调用对象的run()方法 new SystemServer().run(); } private void run() { try { //当系统时间比1970年更早,就设置当前系统时间为1970年 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { 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", ""); } //变更虚拟机的库文件,对于Android 6.0默认采用的是libart.so SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); mProfilerSnapshotTimer = new Timer(); //system_server每隔1小时采用一次,并保存结果到system_server文件 mProfilerSnapshotTimer.schedule(new TimerTask() { @Override public void run() { SamplingProfilerIntegration.writeSnapshot("system_server", null); } }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); } VMRuntime.getRuntime().clearGrowthLimit(); VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); Build.ensureFingerprintProperty(); Environment.setUserRequired(true); BaseBundle.setShouldDefuse(true); BinderInternal.disableBackgroundScheduling(true); BinderInternal.setMaxThreads(sMaxBinderThreads); android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); // 主线程looper就在当前线程运行 Looper.prepareMainLooper(); //加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下 System.loadLibrary("android_servers"); // 检查上次关机过程是否失败,该方法可能不会返回 performPendingShutdown(); // 初始化系统上下文 createSystemContext(); //创建系统服务管理 mSystemServiceManager = new SystemServiceManager(mSystemContext); //将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // 创建并运行所有的Java服务 try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices"); startBootstrapServices(); //启动引导服务 startCoreServices(); //启动核心服务 startOtherServices(); //启动其它服务 } catch (Throwable ex) { throw ex; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // 进入处理消息的循环 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
main()方法的主要是有:
1.调用时间,如果当前系统时间比1970年更早,就设置当前系统时间为1970年 。
2.设置属性persist.sys.dalvik.vm.lib.2的值为当前虚拟机的运行库的路径。
3.调整虚拟机堆的内存。设定虚拟机利用率为0.8。
4.加载android_servers.so库。
5.调用createSystemContext()来获取Context。
6.创建SystemServiceManager的对象mSystemServiceManager,这个对象负责系统Service的启动。
7.启动服务。startBootstrapServices(),startBootstrapServices(),startBootstrapServices()三大方法。
8.调用Loop.loop(),进入处理消息的循环。
private void createSystemContext() { //创建ActivityThread对象 ActivityThread activityThread = ActivityThread.systemMain(); //创建ContextImpl、LoadedApk对象 mSystemContext = activityThread.getSystemContext(); //设置主题 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); }
在createSystemContext()方法里,通过ActivityThread的静态方法systemMain()创建了一个activityThread。然后调用它的getSystemContext()方法来获取系统的Context,最后设置主题。
接下来看看systemMain()方法。
public static ActivityThread systemMain() { //对于低内存的设备,禁用硬件加速 if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } // 创建ActivityThread ActivityThread thread = new ActivityThread(); // 创建Application以及调用其onCreate()方法 thread.attach(true);//代表是系统的应用进程 return thread; }
上面的代码主要是new了一个ActivityThread对象。
同样的我们知道,ActivityThread是应用程序的主线程类,该类同时也存在一个main()主方法,zygote进程在启动过程的最后会在抛出的MethodAndArgsCaller异常中,通过反射来执行ActivityThread类的main()方法。那么这里为什么要用new来创建ActivityThread对象呢?
实际上SystemServer不仅是一个单纯的后台进程,它也是一个运行着组件Service的进程,很多系统的对话框就是从SystemServer中显示出来的,因此,SystemServer本身也需要一个和APK应用类似的上下文环境,创建ActivityThread是获取这个环境的第一步,后面还需要创建SystemContext对象。ActivityThread的attach(boolean)方法中,传入参数true时,表示是在SystemServer中调用。如下代码:
private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) {//进入应用进程的处理流程 ... } else { //进入系统进程。该情况只在SystemServer中处理,设置DDMS时看到的systemserver进程名为system_process android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { mInstrumentation = new Instrumentation(); // 创建应用上下文SystemContext ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); // 创建Application mInitialApplication = context.mPackageInfo.makeApplication(true, null); // 调用Application的onCreate()方法 mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } } ... }
system为true时,创建了ContextImpl和Application对象,最后还调用了Application的onCreate()方法,完全模拟创建一个应用的过程。但是,创建应用上下文环境需要对应的一个apk文件,这个的apk文件是哪个呢?上面的参数中getSystemContext().mPackageInfo正是。
通过跟踪getSystemContext()的代码,最终可以找到在ContextImpl类的createSystemContext(ActivityThread)方法中创建了一个LoadedApk对象。
LoadedApk(ActivityThread activityThread) { mActivityThread = activityThread; mApplicationInfo = new ApplicationInfo(); mApplicationInfo.packageName = "android"; mPackageName = "android"; ... }
LoadedApk对象保存了一个apk文件的信息,它指明了将使用的包名为“android”,而framework-res.apk的包名正是“android”。因此,getSystemContext()方法返回的对象所对象的apk文件就是framework-res.apk。
因此,ActivityThread的SystemMain()方法相当于创建了一个framework-res.apk的上下文环境。
总结:
SystemServer进程是一个应用进程访问底层资源的中间层代理,通过它来启动和管理AMS,PMS等众多服务。
更多相关文章
- Android(安卓)Handler机制之Handler 、MessageQueue 、Looper
- android启动--深入理解启动HOME
- Android经典完美退出方法
- Android(安卓)源码分析之旅3.1--消息机制源码分析
- Android(安卓)创建自定Dialog
- Android(安卓)sqlite 采用execSQL和rawQuery方法完成数据的添删
- android适配器SimpleCursorAdapter的使用以及最后一个参数的作用
- Android(安卓)HandlerThread用法
- 在eclipse中添加插件Green UML