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等众多服务。

更多相关文章

  1. Android(安卓)Handler机制之Handler 、MessageQueue 、Looper
  2. android启动--深入理解启动HOME
  3. Android经典完美退出方法
  4. Android(安卓)源码分析之旅3.1--消息机制源码分析
  5. Android(安卓)创建自定Dialog
  6. Android(安卓)sqlite 采用execSQL和rawQuery方法完成数据的添删
  7. android适配器SimpleCursorAdapter的使用以及最后一个参数的作用
  8. Android(安卓)HandlerThread用法
  9. 在eclipse中添加插件Green UML

随机推荐

  1. mysql中workbench实例详解
  2. MySQL内存使用的查看方式详解
  3. mysql数据插入效率比较
  4. MySQL 8.0.13设置日期为0000-00-00 00:00
  5. 详解Mysql数据库date, datetime类型设置0
  6. Mysql事务隔离级别之读提交详解
  7. MySQL慢日志实践小结
  8. 数据库中间件MyCat的介绍
  9. MySQL半同步复制原理配置与介绍详解
  10. 数据库sql语句优化