SystemServer進程是zygote進程啓動後,主動「分裂」的第一個進程。它負責啓動大量的Android系統核心服務,其重要性不言而喻。一旦該進程崩潰,整個Android系統將從新啓動。java
關鍵類 | 路徑 |
---|---|
com_android_internal_os_Zygote.cpp | frameworks/base/core/jni/com_android_internal_os_Zygote.cpp |
AndroidRuntime.cpp | frameworks/base/core/jni/AndroidRuntime.cpp |
ZygoteInit.java | frameworks/base/core/java/com/android/internal/os/ZygoteInit.java |
Zygote.java | frameworks/base/core/java/com/android/internal/os/Zygote.java |
ActivityThread.java | frameworks/base/core/java/android/app/ActivityThread.java |
ContextImpl.java.java | frameworks/base/core/java/android/app/ContextImpl.java |
LoadedApk.java.java | frameworks/base/core/java/android/app/LoadedApk.java |
SystemServer.java | frameworks/base/services/java/com/android/server/SystemServer.java |
RuntimeInit.java | frameworks/base/core/java/com/android/internal/os/RuntimeInit.java |
SystemServer是什麼?它是Android Java的兩大支柱之一。另一個支柱是專門負責孵化Java進程的Zygote(Zygote進程是整個android系統的根進程)。這兩個支柱倒了任何一個,都會致使Android Java的崩潰(全部由Zygote孵化的Java進程都會被銷燬,而SystemServer就是由Zygote孵化而來)。
若Android Java真的崩潰了,那麼Linux系統中的進程init會從新啓動「兩大支柱」以重建Android Java。
SystemServer和系統服務有着重要的關係,Android系統中幾乎全部的核心服務都是在這個進程中,如:ActivityManagerService、PowerManagerService和WindowManagerService等。當咱們的應用須要使用各類系統服務的時候,其實也是經過與SystemServer進程通信獲取各類服務對象的句柄,進而執行相應的操做。android
SystemServer是由Zygote孵化而來的一個進程,經過ps命令,咱們發現其進程名爲:system_server。bootstrap
在分析zygote進程時,咱們知道當zygote進程進入到java世界後,在ZygoteInit.java中,將調用startSystemServer函數啓動SystemServer進程,其關鍵代碼是:瀏覽器
if (startSystemServer) { Runnable r = forkSystemServer(abiList, socketName, zygoteServer); // fork出system server // {@code r == null} in the parent (zygote) process, and {@code r != null} in the // child (system_server) process. if (r != null) { r.run(); return; } }
咱們看下forkSystemServer():緩存
// 咱們這邊挑出重要代碼講解,詳細代碼分析請參考Zygote篇 /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities);
老樣子,源碼繼續跟下去:網絡
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(); 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, debugFlags); } VM_HOOKS.postForkCommon(); return pid; }
容易看出,該函數經過調用native方法,完成實際的建立操做。該Native方法定義於frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中。 咱們來看看對應的native函數。數據結構
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) { // 進行實際的「分裂」工做 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) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); // 這裏SystemServer進程已經建立出來,pid > 0 說明在父進程中 // 將子進程SystemServer的pid存在zygote進程的全局變量中 gSystemServerPid = pid; // There is a slight window that the system server process has crashed // but it went unnoticed because we haven't published its pid yet. So // we recheck here just to make sure that all is well. int status; if (waitpid(pid, &status, WNOHANG) == pid) { // 小几率,SystemServer進程剛建立,就crash;此時須要重啓zygote ALOGE("System server process %d has died. Restarting Zygote!", pid); RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); } // Assign system_server to the correct memory cgroup. if (!WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) { ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid); } } return pid; }
上述代碼中,實際的「分裂」工做,由函數ForAndSpecializeCommon完成。app
// Utility routine to fork zygote and specialize the child process. 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(); // 註冊信號監聽器 ... ... pid_t pid = fork(); if (pid == 0) { ... ... // 根據傳入參數進行對應的處理,例如設置進程名,設置各類id(用戶id,組id)等 UnsetSigChldHandler(); // 反註冊掉信號監聽器 ... ... } else if (pid > 0) { ... ... } return pid; }
從上面的代碼能夠看出,ForkAndSpecializeCommon最終是經過fork的方式,分裂出子進程。
這裏須要關注一下的是,在zygote進程fork以前,調用SetSigChldHandler函數註冊了一個子進程信號監聽器。因爲子進程共享父進程中的堆及棧信息,所以在子進程中也會有相應的信號處理器。
爲了不該信號監聽器對子進程的影響,能夠看到在子進程中進行了UnsetSigChldHandler的操做。socket
分別看一下SetSigChldHandler和UnsetSigChldHandler所做工做!ide
咱們看看SetSigChldHandler進行了哪些操做。
// Configures the SIGCHLD handler for the zygote process. This is configured // very late, because earlier in the runtime we may fork() and exec() // other processes, and we want to waitpid() for those rather than // have them be harvested immediately. // // This ends up being called repeatedly before each fork(), but there's // no real harm in that. static void SetSigChldHandler() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SigChldHandler; // 該信號監聽器關注子進程結束,對應的處理函數爲SigChldHandler int err = sigaction(SIGCHLD, &sa, NULL); if (err < 0) { ALOGW("Error setting SIGCHLD handler: %s", strerror(errno)); } }
從上面的代碼能夠看出,SetSigChldHandler函數將註冊一個信號處理器,來監聽子進程的死亡。當子進程死亡後,利用SigChldHandler進行操做。須要注意的是,zygote的信號監聽器,關注的是zygote全部的子進程,而不僅是SystemServer進程(每次建立一個新的進程時,zygote都會註冊對應的監聽器)。
那就繼續分析一下SigChldHandler吧:
static void SigChldHandler(int /*signal_number*/) { pid_t pid; int status; ... ... while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { // 經過status判斷子進程結束的緣由,並打印相應的log ... ... // If the just-crashed process is the system_server, bring down zygote // so that it is restarted by init and system server will be restarted // from there. if (pid == gSystemServerPid) { // 上文已經介紹過,gSystemServerPid中記錄了SystemServer的pid ... ... kill(getpid(), SIGKILL); // 若是結束的子進程爲SystemServer,Zygote也將結束本身 } } ... ... }
發現沒?全部zygote的子進程中,zygote只關心了SystemServer的死活。當其它子進程crash時,zygote只打印了log信息。
最後看看UnsetSigChldHandler函數:
// Sets the SIGCHLD handler back to default behavior in zygote children. static void UnsetSigChldHandler() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; int err = sigaction(SIGCHLD, &sa, NULL); if (err < 0) { ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno)); } }
在分析zygote進程時,咱們知道當ZygoteInit.java的startSystemServer函數,經過fork建立出SystemServer進程後,SystemServer進程調用handleSystemServerProcess函數,開始執行本身的工做。
/* For child process */ if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } zygoteServer.closeServerSocket(); // 關閉從zygote進程那裏繼承下來server socket return handleSystemServerProcess(parsedArgs); }
接下來,咱們來看看handleSystemServerProcess函數的主要內容。
/** * Finish remaining work for the newly forked system server process. */ private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { // 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); } // 加載SystemServer對應的文件 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); ... ... if (parsedArgs.invokeWith != null) { ... ... } else { // 利用systemServerClass對應的路徑構建對應的ClassLoader ClassLoader cl = null; if (systemServerClasspath != null) { cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } /* * Pass the remaining arguments to SystemServer. */ // 將剩餘參數及classLoader遞交給ZygoteInit的zygoteInit函數 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */ }
從上面的代碼能夠看出,接下來的流程進入到ZygoteInit的zygoteInit函數。zygoteInit函數將根據classLoader和參數,完成不一樣進程所須要的初始化工做(SystemServer進程與zygote的其它子進程均將使用zygoteInit函數)。
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { if (RuntimeInit.DEBUG) { Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote"); } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit"); RuntimeInit.redirectLogStreams(); RuntimeInit.commonInit(); ZygoteInit.nativeZygoteInit(); return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }
commonInit主要進行一些常規初始化。因爲本身是作通訊的,因此比較關注的是建立UA(user agent): frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static final void commonInit() { ... ... /* * Sets the default HTTP User-Agent used by HttpURLConnection. */ String userAgent = getDefaultUserAgent(); System.setProperty("http.agent", userAgent); ... ... }
User-Agent是Http協議中的一部分,屬於頭域的組成部分,是一種向訪問網站提供你所使用的瀏覽器類型、操做系統、瀏覽器內核等信息的標識。經過這個標識,用戶所訪問的網站能夠顯示不一樣的排版,從而爲用戶提供更好的體驗或者進行信息統計。
函數nativeZyoteInit實如今frameworks/base/core/jni/AndroidRuntime.cpp中,主要用於爲Binder通訊打下基礎。
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz) { gCurRuntime->onZygoteInit(); }
這裏須要關注的是,SystemServer進程中的gCurRuntime指的是什麼呢?
實際上在zygote進程啓動時,在app_main.cpp的main函數中,建立出了AppRuntime:
int main(int argc, char* const argv[]) { ........ AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ........
AppRuntime定義以下:
class AppRuntime : public AndroidRuntime { public: AppRuntime(char* argBlockStart, const size_t argBlockLength) : AndroidRuntime(argBlockStart, argBlockLength) , mClass(NULL) { } ... ... }
看看AppRuntime的父類AndroidRuntime:
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) : mExitWithoutCleanup(false), mArgBlockStart(argBlockStart), mArgBlockLength(argBlockLength) { SkGraphics::Init(); // Pre-allocate enough space to hold a fair number of options. mOptions.setCapacity(20); assert(gCurRuntime == NULL); // one per process gCurRuntime = this; }
從代碼能夠看出,AndroidRuntime初始化時定義了gCurRuntime。gCurRuntime指向對象自身,也就是說gCurRuntime指向的是AppRuntime對象。
因爲SystemServer進程由zygote進程fork出來,因而system server進程中也存在gCurRuntime對象,類型爲AppRuntime。至此咱們知道,Native函數中gCurRuntime->onZygoteInit將調用AppRuntime中的onZygoteInit。
virtual void onZygoteInit() { sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); }
onZygoteInit的用途是啓動一個線程,用於binder通訊。
protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { // 設置一些進程退出的處理策略,可用堆棧上限等 ... ... // Remaining arguments are passed to the start class's static main return findStaticMain(args.startClass, args.startArgs, classLoader); }
繼續分析findStaticMain函數:
private static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { // className爲進行初始化工做的進程類名 // 在SystemServer初始化時,爲com.android.server.SystemServer Class<?> cl; try { // 下面就是經過反射獲得對應類的main方法 cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } ... ... /* * 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. */ return new MethodAndArgsCaller(m, argv); // 捕獲MethodAndArgsCaller異常 }
接下來就進入了SystemServer.java的main函數,其代碼以下:
/** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); // 建立並運行,簡單粗暴! }
這裏比較簡單,只是new出一個SystemServer對象並執行其run方法:
private void run() { try { traceBeginAndSlog("InitBeforeStartServices"); // 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. // 如何系統時鐘早於1970年,則設置系統始終從1970年開始 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); // private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000; SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } ... ... // If the system has "persist.sys.language" and friends set, replace them with // "persist.sys.locale". Note that the default locale at this point is calculated // using the "-Duser.locale" command line flag. That flag is usually populated by // AndroidRuntime using the same set of system properties, but only the system_server // and system apps are allowed to set them. // // NOTE: Most changes made here will need an equivalent change to // core/jni/AndroidRuntime.cpp 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", ""); } // Mmmmmm... more memory! // 清除vm內存增加上限,因爲啓動過程須要較多的虛擬機內存空間 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. // 設置堆棧利用率,GC後會從新計算堆棧空間大小 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); ... ... // Initialize native services. // 加載動態庫libandroid_services.so System.loadLibrary("android_servers"); // Check whether we failed to shut down last time we tried. // This call may not return. // 檢測上次關機過程是否失敗,該方法可能不會返回 performPendingShutdown(); // Initialize the system context. // 在SystemServer進程中也須要建立Context對象,初始化系統上下文 createSystemContext(); // Create the system service manager. // 經過SystemServiceManager的構造方法建立了一個新的SystemServiceManager對象 mSystemServiceManager = new SystemServiceManager(mSystemContext); // SystemServer進程主要是用來構建系統各類service服務,而SystemServiceManager就是這些服務的管理對象 mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); // 將SystemServiceManager對象保存到SystemServer進程中的一個數據結構中 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices } // Start services. try { // 分種類啓動不一樣的system service // 主要用於啓動系統Boot級服務 startBootstrapServices(); // 主要用於啓動系統核心的服務 startCoreServices(); // 主要用於啓動一些非緊要或者非須要及時啓動的服務 startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } ... ... // Loop forever. // //啓動looper,以處理到來的消息,一直循環執行 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
以上就是SystemServer的run函數整個流程,咱們作個簡化,以下:
private void run() { try { // Initialize the system context. createSystemContext(); // 🍁🍁🍁 01.初始化系統上下文 🍁🍁🍁 // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); // 🍁🍁🍁 02.建立系統服務管理 🍁🍁🍁 mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); } finally { traceEnd(); // InitBeforeStartServices } // Start services. // 🍁🍁🍁 03.啓動系統各類服務 🍁🍁🍁 try { startBootstrapServices(); // 啓動引導服務 startCoreServices(); // 啓動核心服務 startOtherServices(); // 啓動其餘服務 SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } ... ... // Loop forever. Looper.loop(); // 一直循環執行 throw new RuntimeException("Main thread loop unexpectedly exited"); }
OK,接下來咱們針對SystemServer所作的三部分工做,進行逐個分析!
private void run() { try { // Initialize the system context. createSystemContext(); // 🍁🍁🍁 01.初始化系統上下文 🍁🍁🍁
跟蹤createSystemContext函數:
private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }
跟蹤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()) { ThreadedRenderer.disable(true); // 對於低內存的設備,禁用硬件加速 } else { ThreadedRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true); return thread; } ActivityThread() { mResourcesManager = ResourcesManager.getInstance(); // 使用單例模式得到一個ResourcesManager實例 }
繼續跟蹤attach函數:
private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ... ... } else { // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. // 設置SystemServer進程在DDMS中顯示的名字爲"system_process" android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); // 如不設置,則顯示"?",沒法調試該進程 try { mInstrumentation = new Instrumentation(); // 首先經過getSystemContext()建立系統上下文,而後建立應用上下文 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); } } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> { synchronized (mResourcesManager) { // We need to apply this change to the resources immediately, because upon returning // the view hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, null /* compat */)) { updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), mResourcesManager.getConfiguration().getLocales()); // This actually changed the resources! Tell everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { mPendingConfiguration = globalConfig; sendMessage(H.CONFIGURATION_CHANGED, globalConfig); } } } }; // 添加回調 ViewRootImpl.addConfigCallback(configChangedCallback); }
能夠看出,attach主要作了三件事:
(1)建立系統上下文:getSystemContext() --> createSystemContext() --> new ContextImpl()
(2)建立應用上下文 ContextImpl.createAppContext() --> new ContextImpl()
(3)添加回調configChangedCallback到ViewRootImpl
getSystemContext():
public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } }
跟蹤createSystemContext函數:
static ContextImpl createSystemContext(ActivityThread mainThread) { // 這邊new出來的LoadedApk將做爲建立應用上下文的參數packageInfo LoadedApk packageInfo = new LoadedApk(mainThread); // ContextImpl()建立系統上下文 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); context.setResources(packageInfo.getResources()); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); return context; }
ContextImpl.createAppContext():
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); // ContextImpl()建立應用上下文 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); context.setResources(packageInfo.getResources()); return context; }
咱們能夠看出:new ContextImpl時,系統上下文和應用上下文的參數是同樣的,createAppContext()中的參數packageInfo,就是createSystemContext()中new的LoadedApk。
建立完成以後,系統上下文賦值給了ActivityThread的成員變量mSystemContext,而應用上下文只是做爲函數中的局部變量臨時使用。
咱們回顧一下建立上下文的代碼:
try { mInstrumentation = new Instrumentation(); // 首先經過getSystemContext()建立系統上下文,而後建立應用上下文 ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); // 建立Application mInitialApplication = context.mPackageInfo.makeApplication(true, null); // 調用Application的onCreate() mInitialApplication.onCreate();
接下來就繼續看下建立Application的流程:
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } Application app = null; String appClass = mApplicationInfo.className; // 參數forceDefaultAppClass爲true if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); // 此LoadedApk對象是createSystemContext時new的,mPackageName="android" if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); } // 又建立了一個局部應用上下文 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); // 建立Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { ... ... } // 將前面建立的app添加到應用列表 mActivityThread.mAllApplications.add(app); mApplication = app; ... ... return app; }
這一步主要建立了一個ActivityThread對象,而後執行了該對象的attach()方法,attach()方法中建立了系統上下文mSystemContext(類型爲ContextImpl),並建立Application對象。
系統上下文中,new了一個LoadedApk的成員變量,並將ActivityThread對象傳給LoadedApk成員,後面的Application對象就是LoadedApk使用ActivityThread建立的,LoadedApk建立了Application對象後,將Application添加到ActivityThread的應用列表中。
咱們回顧下相關代碼:
// Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
這一步比較簡單,只是new了一個SystemServiceManager,並將其添加到本地服務列表中。mSystemContext爲第一步中建立的系統上下文。本地服務列表是以類爲key保存的一個列表,即列表中某種類型的對象最多隻能有一個。
public class SystemServiceManager { ... ... // Services that should receive lifecycle events. // 系統服務列表,系統服務必須繼承SystemService private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); // 當前處於開機過程的哪一個階段,SystemService.PHASE_XXXXX private int mCurrentPhase = -1; SystemServiceManager(Context context) { mContext = context; } /** * Starts a service by class name. * * @return The service instance. */ @SuppressWarnings("unchecked") // 經過類名啓動系統服務,可能會找不到類而拋異常 public SystemService startService(String className) { final Class<SystemService> serviceClass; try { serviceClass = (Class<SystemService>)Class.forName(className); } catch (ClassNotFoundException ex) { Slog.i(TAG, "Starting " + className); throw new RuntimeException("Failed to create service " + className + ": service class not found, usually indicates that the caller should " + "have called PackageManager.hasSystemFeature() to check whether the " + "feature is available on this device before trying to start the " + "services that implement it", ex); } return startService(serviceClass); } /** * Creates and starts a system service. The class must be a subclass of * {@link com.android.server.SystemService}. * * @param serviceClass A Java class that implements the SystemService interface. * @return The service instance, never null. * @throws RuntimeException if the service fails to start. */ @SuppressWarnings("unchecked") // 建立並啓動系統服務,系統服務類必須繼承SystemService public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); Slog.i(TAG, "Starting " + name); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name); // Create the service. if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } catch (InstantiationException ex) { throw new RuntimeException("Failed to create service " + name + ": service could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (NoSuchMethodException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (InvocationTargetException ex) { throw new RuntimeException("Failed to create service " + name + ": service constructor threw an exception", ex); } startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart"); } /** * Starts the specified boot phase for all system services that have been started up to * this point. * * @param phase The boot phase to start. */ // 通知系統服務到了開機的哪一個階段,會遍歷調用全部系統服務的onBootPhase()函數 public void startBootPhase(final int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; Slog.i(TAG, "Starting phase " + mCurrentPhase); try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); long time = SystemClock.elapsedRealtime(); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName()); try { service.onBootPhase(mCurrentPhase); } catch (Exception ex) { throw new RuntimeException("Failed to boot service " + service.getClass().getName() + ": onBootPhase threw an exception during phase " + mCurrentPhase, ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase"); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } }
try { startBootstrapServices(); // 啓動引導服務 startCoreServices(); // 啓動核心服務 startOtherServices(); // 啓動其餘服務
首先來看下startBootstrapServices():
private void startBootstrapServices() { ... ... // 啓動Installer服務,阻塞等待與installd創建socket通道 Installer installer = mSystemServiceManager.startService(Installer.class); mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); // 啓動ActivityManagerService(AMS),關於AMS咱們後面會詳細講解 mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); // 啓動PowerManagerService mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // PowerManagerService就緒,AMS初始化電源管理 mActivityManagerService.initPowerManagement(); // Bring up recovery system in case a rescue party needs a reboot if (!SystemProperties.getBoolean("config.disable_noncore", false)) { traceBeginAndSlog("StartRecoverySystemService"); mSystemServiceManager.startService(RecoverySystemService.class); traceEnd(); } RescueParty.noteBoot(mSystemContext); // 啓動LightsService mSystemServiceManager.startService(LightsService.class); // 啓動DisplayManagerService(before package manager) mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); // 初始化package manager以前,須要默認顯示。阻塞,10s超時,see DisplayManagerService.onBootPhase() 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. if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_package_manager_init_start", (int) SystemClock.elapsedRealtime()); } // 啓動PackageManagerService mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); ... ... // 將UserManagerService添加到服務列表,該服務是在PackageManagerService中初始化的 mSystemServiceManager.startService(UserManagerService.LifeCycle.class); // Initialize attribute cache used to cache resources from packages. // 初始化用來緩存包資源的屬性緩存 AttributeCache.init(mSystemContext); // Set up the Application instance for the system process and get started. // 設置AMS mActivityManagerService.setSystemProcess(); ... ... // The sensor service needs access to package manager service, app ops // service, and permissions service, therefore we start it after them. // Start sensor service in a separate thread. Completion should be checked // before using it. mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(START_SENSOR_SERVICE); // 啓動傳感器服務(native 服務,依賴PackageManagerService、AppOpsService、permissions service) startSensorService(); traceLog.traceEnd(); }, START_SENSOR_SERVICE); }
這步首先等待installd啓動完成,而後啓動一些相互依賴的關鍵服務。所建立的服務:ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,sensor服務。
接下來繼續看下核心服務:
/** * Starts some essential services that are not tangled up in the bootstrap process. */ private void startCoreServices() { mSystemServiceManager.startService(DropBoxManagerService.class); // 啓動BatteryService,用於統計電池電量,須要LightService mSystemServiceManager.startService(BatteryService.class); // 啓動UsageStatsService,用於統計應用使用狀況 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); // 啓動WebViewUpdateService mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); }
啓動服務DropBoxManagerService、BatteryService,UsageStatsService,WebViewUpdateService。
代碼很長(1200多行...),可是邏輯簡單,主要是啓動各類服務。
/** * Starts a miscellaneous grab bag of stuff that has yet to be refactored * and organized. */ private void startOtherServices() { ... ... try { ... ... traceBeginAndSlog("StartSchedulingPolicyService"); // 調度策略 ServiceManager.addService("scheduling_policy", new SchedulingPolicyService()); traceEnd(); traceBeginAndSlog("StartTelecomLoaderService"); mSystemServiceManager.startService(TelecomLoaderService.class); traceEnd(); traceBeginAndSlog("StartTelephonyRegistry"); // 提供電話註冊、管理服務,能夠獲取電話的連接狀態、信號強度等 telephonyRegistry = new TelephonyRegistry(context); ServiceManager.addService("telephony.registry", telephonyRegistry); traceEnd(); traceBeginAndSlog("StartEntropyMixer"); // 隨機數相關,原名EntropyService mEntropyMixer = new EntropyMixer(context); traceEnd(); mContentResolver = context.getContentResolver(); // The AccountManager must come before the ContentService traceBeginAndSlog("StartAccountManagerService"); // 提供全部帳號、密碼、認證管理等等的服務 mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS); traceEnd(); traceBeginAndSlog("StartContentService"); // ContentProvider服務,提供跨進程數據交換 mSystemServiceManager.startService(CONTENT_SERVICE_CLASS); traceEnd(); traceBeginAndSlog("InstallSystemProviders"); mActivityManagerService.installSystemProviders(); traceEnd(); traceBeginAndSlog("StartVibratorService"); // 振動器服務 vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator); traceEnd(); ... ... traceBeginAndSlog("InitWatchdog"); // 初始化 Watchdog final Watchdog watchdog = Watchdog.getInstance(); watchdog.init(context, mActivityManagerService); traceEnd(); traceBeginAndSlog("StartInputManagerService"); // 事件傳遞分發服務 inputManager = new InputManagerService(context); traceEnd(); traceBeginAndSlog("StartWindowManagerService"); // 窗口管理服務 // WMS needs sensor service ready ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE); mSensorServiceStart = null; wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore, new PhoneWindowManager()); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); traceEnd(); ... ... } ... ... LockSettingsService // 屏幕鎖定服務,管理每一個用戶的相關鎖屏信息 DeviceIdleController // Doze模式的主要驅動,參考「深刻Android 'M' Doze」 DevicePolicyManagerService // 提供一些系統級別的設置及屬性 StatusBarManagerService // 狀態欄管理服務 ClipboardService // 系統剪切板服務 NetworkManagementService // 網絡管理服務 TextServicesManagerService // 文本服務,例如文本檢查等 NetworkScoreService // 網絡評分服務 NetworkStatsService // 網絡狀態服務 NetworkPolicyManagerService // 網絡策略服務 WifiP2pService // Wifi Direct服務 WifiService // Wifi服務 WifiScanningService // Wifi掃描服務 RttService // Wifi相關 EthernetService // 以太網服務 ConnectivityService // 網絡鏈接管理服務 NsdService // 網絡發現服務 ... ... NotificationManagerService // 通知欄管理服務 DeviceStorageMonitorService // 磁盤空間狀態檢測服務 LocationManagerService // 位置服務,GPS、定位等 CountryDetectorService // 檢測用戶國家 SearchManagerService // 搜索管理服務 DropBoxManagerService // 用於系統運行時日誌的存儲於管理 WallpaperManagerService // 壁紙管理服務 AudioService // AudioFlinger的上層管理封裝,主要是音量、音效、聲道及鈴聲等的管理 DockObserver // 若是系統有個座子,當手機裝上或拔出這個座子的話,就得靠他來管理了 WiredAccessoryManager // 監視手機和底座上的耳機 UsbService // USB服務 SerialService // 串口服務 TwilightService // 指出用戶當前所在位置是否爲晚上,被UiModeManager等用來調整夜間模式。 BackupManagerService // 備份服務 AppWidgetService // 提供Widget的管理和相關服務 VoiceInteractionManagerService // 語音交互管理服務 DiskStatsService // 磁盤統計服務,供dumpsys使用 SamplingProfilerService // 用於耗時統計等 NetworkTimeUpdateService // 監視網絡時間,當網絡時間變化時更新本地時間。 CommonTimeManagementService // 管理本地常見的時間服務的配置,在網絡配置變化時從新配置本地服務。 CertBlacklister // 提供一種機制更新SSL certificate blacklist DreamManagerService // 屏幕保護 AssetAtlasService // 負責將預加載的bitmap組裝成紋理貼圖,生成的紋理貼圖能夠被用來跨進程使用,以減小內存。 PrintManagerService // 打印服務 HdmiControlService // HDMI控制服務 FingerprintService // 指紋服務 ... ... }
以上代碼僅按順序列出啓動的服務,有些服務根據條件,如是不是工廠模式,或系統屬性配置,選擇性啓動,這裏不考慮條件判斷和異常處理。
自此,SystemServer相關源碼分析完畢。