圖解 Android 系列(三)探索 SystemServer 進程建立過程

介紹

這是一個連載的系列「圖解 Android 系列」,我將持續爲你們提供儘量通俗易懂的 Android 源碼分析。java

全部引用的源碼片斷,我都會在第一行標明源文件完整路徑。爲了文章篇幅考慮源碼中間可能有刪減,刪減部分會用省略號代替。linux

本系列源碼基於:Android Oreo(8.0)android

SystemServer 進程

SystemServer 進程是由 zygote 進程 fork 出來的,進程名爲 system_server,該進程承載着 Framework 的核心服務。c++

SystemServer 啓動

在上篇 深刻理解 init 與 zygote 進程 中介紹到 zygote 進程在啓動過程當中會調用到 startSystemServer() 方法,可得知該方法是 SystemServer 進程啓動的起點,下面咱們接着來分析 SystemServer 的啓動流程。git

ZygoteInit.java

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

public static void main(String argv[]) {
  // ...
  try {
    // ...
    boolean startSystemServer = false;
    // ...
    for (int i = 1; i < argv.length; i++) {
      if ("start-system-server".equals(argv[i])) {
        startSystemServer = true;
      }
      // ...
    }
    // ...
    if (startSystemServer) { // 啓動 system_server
      startSystemServer(abiList, socketName, zygoteServer);
    }

    // 進入循環模式
    zygoteServer.runSelectLoop(abiList);

    zygoteServer.closeServerSocket();
  } catch (Zygote.MethodAndArgsCaller caller) {
    caller.run();
  } catch (Throwable ex) {
    // ...
  }
}
複製代碼

能夠看到這裏調用了 startSystemServer() 方法來啓動 SystemServer 進程。github

startSystemServer()

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

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller, RuntimeException {
  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
  );
  /* Containers run without this capability, so avoid setting it in that case */
  if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, 
                                   false)) {
    capabilities |= 
      posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
  }
  /* 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,1021,1023,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 {
    // 用於解析參數,生成目標格式
    parsedArgs = new ZygoteConnection.Arguments(args);
    ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
    ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

    /* Request to fork the system server process */
    // fork 子進程,用於運行 system_server,下面分析
    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 */
  // 進入子進程 system_server
  if (pid == 0) { // pid==0 意味着子進程建立成功
    if (hasSecondZygote(abiList)) {
      waitForSecondaryZygote(socketName);
    }

    zygoteServer.closeServerSocket();
    // 完成 system_server 進程剩餘的工做,下面分析
    handleSystemServerProcess(parsedArgs);
  }

  return true;
}
複製代碼

startSystemServer() 方法主要是準備參數並 fork 新進程,從上面能夠看出 SystemServer 進程參數信息爲 uid=1000,gid=1000,進程名爲 sytem_server,從 zygote 進程 fork 新進程後,須要關閉 zygote 原有的 socket。另外,對於有兩個 zygote 進程狀況,需等待第 2 個 zygote 建立完成。網絡

forkSystemServer()

//frameworks/base/core/java/com/android/internal/os/Zygote.java

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
  
  VM_HOOKS.preFork();
  // Resets nice priority for zygote process.
  resetNicePriority();
  // 調用 native 方法 fork system_server 進程,下面分析
  int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, 
          rlimits, permittedCapabilities, effectiveCapabilities);
  // Enable tracing as soon as we enter the system_server.
  if (pid == 0) {
    Trace.setTracingEnabled(true);
  }
  VM_HOOKS.postForkCommon();
  return pid;
}

native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
複製代碼

nativeForkSystemServer() 是一個 JNI 方法在 AndroidRuntime.cpp 中註冊的,調用com_android_internal_os_Zygote.cpp 中的 register_com_android_internal_os_Zygote() 方法創建 native 方法的映射關係。app

nativeForkSystemServer()

//frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

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_DEFAULT, NULL, 
          NULL, true, NULL, NULL, NULL, NULL);
  if (pid > 0) {
      // zygote 進程,檢測 system_server 進程是否建立
      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;
}
複製代碼

當 system_server 進程建立失敗時,將會重啓 zygote 進程。這裏須要注意,對於 Android 5.0 以上系統,有兩個 zygote 進程,分別是 zygote、zygote64 兩個進程,system_server 的父進程,通常來講 64 位系統其父進程是 zygote64 進程。socket

  • 當 kill system_server 進程後,只重啓 zygote64 和 system_server,不重啓 zygote;
  • 當 kill zygote64 進程後,只重啓 zygote64 和 system_server,也不重啓 zygote;
  • 當 kill zygote 進程,則重啓 zygote、zygote64 以及 system_server。

ForkAndSpecializeCommon()

//frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static pid_t ForkAndSpecializeCommon(JNIEnv *env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jintArray fdsToIgnore, jstring instructionSet, jstring dataDir) {
  SetSigChldHandler(); // 設置子進程的 signal 信號處理函數
  // ...
  pid_t pid = fork(); // fork 子進程
  if (pid == 0) { // 進入子進程
    // The child process.
    gMallocLeakZygoteChild = 1;

    // Set the jemalloc decay time to 1.
    mallopt(M_DECAY_TIME, 1);

    // 關閉並清除文件描述符
    DetachDescriptors(env, fdsToClose);
    // ...
    if (!is_system_server) {
      // 對於非 system_server 子進程,則建立進程組
      int rc = createProcessGroup(uid, getpid());
      // ...
    }

    SetGids(env, javaGids); // 設置設置 group
    SetRLimits(env, javaRlimits); // 設置資源 limit

    if (use_native_bridge) {
      ScopedUtfChars isa_string(env, instructionSet);
      ScopedUtfChars data_dir(env, dataDir);
      android::PreInitializeNativeBridge(data_dir.c_str(), 
                                         isa_string.c_str());
    }

    int rc = setresgid(gid, gid, gid);
    // ...
    rc = setresuid(uid, uid, uid);
    // ...
    SetCapabilities(env, permittedCapabilities, 
                    effectiveCapabilities, permittedCapabilities);
    SetSchedulerPolicy(env); // 設置調度策略

    // ...
    // 建立 selinux 上下文
    rc = selinux_android_setcontext(uid, is_system_server, 
                                    se_info_c_str, se_name_c_str);
    // ...
    if (se_info_c_str == NULL && is_system_server) {
      se_name_c_str = "system_server";
    }
    if (se_info_c_str != NULL) {
      // 設置線程名爲 system_server,方便調試
      SetThreadName(se_name_c_str);
    }

    delete se_info;
    delete se_name;

    // 設置子進程的 signal 信號處理函數爲默認函數
    UnsetSigChldHandler();
    // 等價於調用 zygote.callPostForkChildHooks()
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks,
                              debug_flags, is_system_server, 
                              instructionSet);
  } else if (pid > 0) {
    // 進入父進程,即 zygote 進程
    // ...
  }
  return pid;
}
複製代碼

fork() 建立新進程,採用 copy on write 方式,這是 Linux 建立進程的標準方法,會有兩次 return,對於 pid==0 爲子進程的返回,對於 pid>0 爲父進程的返回。ide

到此 system_server 進程已完成了建立的全部工做,接下來開始了system_server 進程的真正工做。在前面 startSystemServer() 方法中,zygote 進程執行完 forkSystemServer() 後,新建立出來的system_server 進程便進入 handleSystemServerProcess() 方法。

handleSystemServerProcess()

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

private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws Zygote.MethodAndArgsCaller {

  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);
    // ...
  }

  // 此處爲空,走 else 分支
  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(args, 0, amendedArgs, 2, args.length);
      args = amendedArgs;
    }
    // 啓動應用進程
    WrapperInit.execApplication(parsedArgs.invokeWith,
           parsedArgs.niceName, parsedArgs.targetSdkVersion,
           VMRuntime.getCurrentInstructionSet(), null, args);
  } else {
    ClassLoader cl = null;
    if (systemServerClasspath != null) {
      cl = createPathClassLoader(systemServerClasspath, 
                                 parsedArgs.targetSdkVersion);
      // 建立類加載器,並賦予當前線程
      Thread.currentThread().setContextClassLoader(cl);
    }

    // system_server 進入此分支
    ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, 
                          parsedArgs.remainingArgs, cl);
  }

  /* should never reach here */
}
複製代碼

到這裏 SystemServer 進程已經建立完了,SystemServer 進程是 Zygote 進程 fork 出來的第一個進程。Zygote 進程和 SystemServer 進程是 Java 世界的基礎,任何一個進程死亡都會致使 Java 世界的奔潰。因此若是子進程 SystemServer 掛了,Zygote 進程就會自殺,致使 Zygote 進程會重啓。

SystemServer fork 過程

zygoteInit()

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

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
  
  RuntimeInit.redirectLogStreams(); // 重定向 log 輸出
  RuntimeInit.commonInit(); // 通用的一些初始化
  ZygoteInit.nativeZygoteInit(); // zygote 初始化
  // 應用初始化
  RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
複製代碼

SystemServer 進程建立完成後會調用 ZygoteInit.zygoteInit() 進行初始化。

commonInit()

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

protected static final void commonInit() {
  // 設置默認的未捕捉異常處理方法
  Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
  Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());

  // 設置市區,中國時區爲"Asia/Shanghai"
  TimezoneGetter.setInstance(new TimezoneGetter() {
    @Override
    public String getId() {
      return SystemProperties.get("persist.sys.timezone");
    }
  });
  TimeZone.setDefault(null);

  // 重置 log 配置
  LogManager.getLogManager().reset();
  new AndroidConfig();

  // 設置默認的 HTTP User-agent 格式,用於 HttpURLConnection
  String userAgent = getDefaultUserAgent();
  System.setProperty("http.agent", userAgent);

  // 設置 socket 的 tag,用於網絡流量統計
  NetworkManagementSocketTagger.install();

  initialized = true;
}
複製代碼

nativeZygoteInit()

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

private static final native void nativeZygoteInit();
複製代碼

nativeZygoteInit() 方法在 AndroidRuntime.cpp 中,進行了 JNI 映射,對應下面的方法。

//frameworks/base/core/jni/AndroidRuntime.cpp

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();
  proc->startThreadPool(); // 啓動新 binder 線程
}
複製代碼

ProcessState::self() 是單例模式,主要工做是調用 open() 打開 /dev/binder 驅動設備,再利用 mmap() 映射內核的地址空間,將 Binder 驅動的 fd 賦值 ProcessState 對象中的變量 mDriverFD,用於交互操做。startThreadPool() 是建立一個新的 binder 線程,不斷進行 talkWithDriver(),這裏先有個印象,關於 Binder 驅動相關細節咱們在後面章節再討論。

applicationInit()

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

protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
  // true 表明應用程序退出時不調用 AppRuntime.onExit(),不然會在退出前調用
  nativeSetExitWithoutCleanup(true);

  // 設置虛擬機的內存利用率參數值爲 0.75
  VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
  VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

  final Arguments args;
  try {
    args = new Arguments(argv); // 解析參數
  } catch (IllegalArgumentException ex) {
    Slog.e(TAG, ex.getMessage());
    // let the process exit
    return;
  }

  // The end of of the RuntimeInit event (see #zygoteInit).
  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

  // 調用 startClass 的 static 方法 main()
  invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
複製代碼

在 startSystemServer() 方法中經過硬編碼初始化參數,可知此處 args.startClass 爲 com.android.server.SystemServer

invokeStaticMain()

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

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
  Class<?> cl;

  try {
    cl = Class.forName(className, true, classLoader);
  } catch (ClassNotFoundException ex) {
    // ...
  }

  Method m;
  try {
    m = cl.getMethod("main", new Class[] { String[].class });
  } catch (NoSuchMethodException ex) {
    // ...
  } catch (SecurityException ex) {
    // ...
  }

  int modifiers = m.getModifiers();
  if (! (Modifier.isStatic(modifiers) 
         && Modifier.isPublic(modifiers))) {
    // ...
  }

  // 經過拋出異常,回到 ZygoteInit.main() 的 catch 中
  // 這樣作好處是能清空棧幀,提升棧幀利用率
  throw new Zygote.MethodAndArgsCaller(m, argv);
}
複製代碼

MethodAndArgsCaller

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

public static void main(String argv[]) {
  // ...
  try {
    // ...
    if (startSystemServer) { // 啓動 system_server
      startSystemServer(abiList, socketName, zygoteServer);
    }
    // ...
  } catch (Zygote.MethodAndArgsCaller caller) {
    caller.run();
  } catch (Throwable ex) {
    // ...
  }
}
複製代碼

從文章開頭啓動 SystemServer 進程到如今能夠看到,是 invokeStaticMain() 方法中拋出的異常 Zygote.MethodAndArgsCaller,從而進入 caller.run() 方法。

//frameworks/base/core/java/com/android/internal/os/Zygote.java

public static class MethodAndArgsCaller extends Exception implements Runnable {
  private final Method mMethod;
  private final String[] mArgs;

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

  public void run() {
    try {
      // 根據傳遞過來的參數,
      // 可知此處經過反射機制調用的是 SystemServer.main() 方法
      mMethod.invoke(null, new Object[] { mArgs });
    } 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);
    }
  }
}
複製代碼

到此,總算是進入到了 SystemServer 類的 main() 方法。

SystemServer.main()

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

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);
    }

    // 將 timezone 默認設置爲 GMT
    String timezoneProperty =
      SystemProperties.get("persist.sys.timezone");
    if (timezoneProperty == null || timezoneProperty.isEmpty()) {
      SystemProperties.set("persist.sys.timezone", "GMT");
    }

    // 根據配置設置系統語言
    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", "");
    }

    // The system server should never make non-oneway calls
    Binder.setWarnOnBlocking(true);

    // Here we go!
    Slog.i(TAG, "Entered the Android system server!");
    int uptimeMillis = (int) SystemClock.elapsedRealtime();
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, 
                        uptimeMillis);
    if (!mRuntimeRestart) {
      MetricsLogger.histogram(null, "boot_system_server_init", 
                              uptimeMillis);
    }

    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);
    }

    // 清除 vm 內存增加上限,因爲啓動過程須要較多的虛擬機內存空間
    VMRuntime.getRuntime().clearGrowthLimit();

    // 設置內存的可能有效使用率爲 0.8
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

    // 針對部分設備依賴於運行時就產生指紋信息,所以須要在開機完成前已經定義
    Build.ensureFingerprintProperty();

    // 訪問環境變量前,須要明確地指定用戶
    Environment.setUserRequired(true);

    // 確保當前系統進程的 binder 調用,
    // 老是運行在前臺優先級(foreground priority)
    BaseBundle.setShouldDefuse(true);

    // Ensure binder calls into the system always run at foreground priority.
    BinderInternal.disableBackgroundScheduling(true);

    // 增長 system_server 中的 binder 線程數
    BinderInternal.setMaxThreads(sMaxBinderThreads);

    // 準備主線程 looper
    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.setRuntimeRestarted(mRuntimeRestart);
    // 將 mSystemServiceManager 添加到本地服務的成員 sLocalServiceObjects
    LocalServices.addService(SystemServiceManager.class, 
                             mSystemServiceManager);
    // Prepare the thread pool for init tasks that can be parallelized
    SystemServerInitThreadPool.get();
  } finally {
    traceEnd();  // InitBeforeStartServices
  }

  // 啓動各類系統服務
  try {
    // 啓動引導服務
    startBootstrapServices();
    // 啓動核心服務
    startCoreServices();
    // 啓動其餘服務
    startOtherServices();
    SystemServerInitThreadPool.shutdown();
  } catch (Throwable ex) {
    throw ex;
  } finally {
    traceEnd();
  }

  // 用於 debug 版本,將 log 事件不斷循環地輸出到 dropbox(用於分析)
  if (StrictMode.conditionallyEnableDebugLogging()) {
    Slog.i(TAG, "Enabled StrictMode for system server main thread.");
  }
  if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
    int uptimeMillis = (int) SystemClock.elapsedRealtime();
    MetricsLogger.histogram(null, "boot_system_server_ready", 
                            uptimeMillis);
    final int MAX_UPTIME_MILLIS = 60 * 1000;
    if (uptimeMillis > MAX_UPTIME_MILLIS) {
      Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
               "SystemServer init took too long. uptimeMillis=" + 
               uptimeMillis);
    }
  }

  // 一直循環執行
  Looper.loop();
  throw new RuntimeException("Main thread loop unexpectedly exited");
}
複製代碼

run() 方法中的主要工做以下:

  • 檢驗時間:若是當前時間早於1970年,則設置當前時間爲1970年,防止初始化出錯。
  • 設置系統的語言環境等。
  • 設置當前虛擬機的運行庫路徑 persist.sys.dalvik.vm.lib.2
  • 設置虛擬機的堆內存,虛擬機堆利用率爲 0.8。
  • 調用 prepareMainLooper() 初始化當前線程的 Looper。
  • 加載 ibandroid_servers.so 庫。
  • 調用 createSystemContext() 建立 System 的 context。
  • 建立大管家 SystemServiceManager 的對象 mSystemServiceManager,負責系統 Service 的管理。
  • 調用 startBootstrapServices()startCoreServices()startOtherServices(),建立和運行系統中全部的服務。
  • 調用 Looper.loop(),開啓消息循環。

總結

到這裏 SystemServer 進程已經啓動起來了,咱們來回顧下建立過程,以下圖:

SystemServer 建立過程

能夠看到 SystemServer 進程由 Zygote 進程 fork 出來,接着會初始化虛擬機環境,而後建立 SystemServiceManager 大管家,啓動系統服務,最後進入 loop 狀態。

這篇文章咱們分析到這裏了,下一篇咱們繼續分析 SystemServer 進程的後續流程。

參考資料

個人 Github

github.com/jeanboydev/…

個人公衆號

歡迎關注個人公衆號,分享各類技術乾貨,各類學習資料,職業發展和行業動態。

Android 波斯灣

技術交流羣

歡迎加入技術交流羣,來一塊兒交流學習。

QQ 技術交流羣

QQ 技術交流羣
相關文章
相關標籤/搜索