--- title: 'SystemServer' disqus: kyleAlien --- SystemServer === ## OverView of Content [TOC] ## SystemServer SystemServer 是由 init 進程 Fork 出來,而 **AMS、PKMS、PMS、WMS... 等等系統服務 也是由 SystemServer 啟動** > ![](https://i.imgur.com/XQeXK4j.png) ### SystemServer Context * SystemServer 啟動 Context 流程 ```java= // /services/java/com/android/server/SystemServer.java private void run() { try { ... 省略部分 // Initialize the system context. createSystemContext(); ... 省略部分 } /*省略 catch 部分*/ } private void createSystemContext() { // 創建一個 ActivityThread 對象 ActivityThread activityThread = ActivityThread.systemMain(); // 取得 系統 Context mSystemContext = activityThread.getSystemContext(); // 設定系統主題 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); } ``` 1. 創建 System 級別的 [**ActivityThread**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java) 對象 ```java= // /core/java/android/app/ActivityThread.java public static ActivityThread systemMain() { ThreadedRenderer.initForSystemProcess(); // 創建一個 ActivityThread 對象 ActivityThread thread = new ActivityThread(); // 繼續分析 attach 方法 (注意傳入參數為 true) thread.attach(true, 0); return thread; } ``` 2. **ActivityThread `#attach` 函數會創建 Instrumentation 對象**,該對象可以管理 Acitivty ```java= // ActivityThread.java @UnsupportedAppUsage private void attach(boolean system, long startSeq) { ... 省略部分 if (!system) { // 一般 APP ... 省略部分 } else { // 系統 try { // 創建儀錶板 Instrumentation mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); // 創 App Context,接著看 createAppContext、getSystemContext 方法 ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); // 創建 Application 對象 // makeApplication 下個小節分析 mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } /* 省略 catch */ } } ``` 3. [**ContextImpl#createAppContext**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ContextImpl.java) 創建 **ContextImpl 對象** (APP 等級) ```java= // ContextImpl.java @UnsupportedAppUsage static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { return createAppContext(mainThread, packageInfo, null); } static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo, String opPackageName) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName); context.setResources(packageInfo.getResources()); context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI : CONTEXT_TYPE_NON_UI; return context; } ``` 4. 取得 ActivityThread 的系統 Context 對象 ```java= // ActivityThread.java @Override @UnsupportedAppUsage public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } } // 取得 系統 UiContext @Override public ContextImpl getSystemUiContext() { synchronized (this) { if (mSystemUiContext == null) { mSystemUiContext = ContextImpl.createSystemUiContext(getSystemContext()); } return mSystemUiContext; } } ``` 5. [**ContextImpl#createSystemContext**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ContextImpl.java) 創建系統 **Context (系統等級)**、**LoadedApk** 對象 ```java= // ContextImpl.java static ContextImpl createSystemContext(ActivityThread mainThread) { // 創建 LoadedApk,用來加載 APK 文件 LoadedApk packageInfo = new LoadedApk(mainThread); // 創建 ContextImpl ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); // 設定 Package Resoureces context.setResources(packageInfo.getResources()); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); return context; } ``` > ![](https://i.imgur.com/Xj60j8n.png) ### ServiceManager - Applicatoin 創建 * 複習前面在 `ActivityThread#attach`函數時,會呼叫 ContextImp 中的 LoadedApk 的 **makeApplication 函數** ```java= // ActivityThread.java @UnsupportedAppUsage private void attach(boolean system, long startSeq) { ... 省略部分 if (!system) { ... 省略部分 } else { try { // 創建儀錶板 Instrumentation mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); // 創建 Application 對象 mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } /* 省略 catch */ } } ``` * LoadedApk 又是透過 Instrumentation 來創建 Application 對象,並複寫 R 檔(ID 資源檔) ```java= // ContextImpl.java static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); // 設定 Context 資源 context.setResources(packageInfo.getResources()); return context; } // ---------------------------------------------------------- // LoadedApk.java public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { // 一個 LoadedApk 對應一個 mApplication if (mApplication != null) { return mApplication; } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); Application app = null; // 若 AndroidManifest.xml 有設定 className 就會使用 User 指定的 Application // 取得 String Name 就可以透過反射創建 String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { // 預設使用 android.app.Application appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader"); initializeJavaContextClassLoader(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); // 透過 Instrumentation 創建 Application 對象 app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } /*省略 catch*/ mActivityThread.mAllApplications.add(app); mApplication = app; if (instrumentation != null) { try { // 呼叫 Application#onCreate 函數 instrumentation.callApplicationOnCreate(app); } /*省略 catch*/ } // Rewrite the R 'constants' for all library apks. SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(); final int N = packageIdentifiers.size(); for (int i = 0; i < N; i++) { final int id = packageIdentifiers.keyAt(i); if (id == 0x01 || id == 0x7f) { continue; } rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return app; } ``` * 最終透過反射創建 Application (取得 AndroidManifest.xml 設定的 name) > ![](https://i.imgur.com/F5FCgrC.png) ```java= // Instrumentation public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { // 接著看 instantiateApplication Application app = getFactory(context.getPackageName()) .instantiateApplication(cl, className); app.attach(context); return app; } // AppComponectFactory.java public @NonNull Application instantiateApplication(@NonNull ClassLoader cl, @NonNull String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { // 使用反射創建 Application return (Application) cl.loadClass(className).newInstance(); } ``` > ![](https://i.imgur.com/VgShTp0.png) ### [SystemServiceManager](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/core/java/com/android/server/SystemServiceManager.java) 建構 * **SystemServiceManager 類是用來管理、啟動系統的服務**,SystemServiceManager 對象建構是在 `SysemServer`#`run` 函數,**在建構完該函數後就會使用它來啟動其他服務**,其中就包括 AMS、WMS、PMS... 等等 ```java= // /android/server/SystemServer.java public final class SystemServer implements Dumpable { public static void main(String[] args) { new SystemServer().run(); } private void run() { ... 省略部分 try { t.traceBegin("StartServices"); // 創建 SystemServiceManager 對象 mSystemServiceManager = new SystemServiceManager(mSystemContext); try { t.traceBegin("StartServices"); startBootstrapServices(t); // 引導服務 startCoreServices(t); // 核心服務 startOtherServices(t); // 啟動各種類型的 Services } /* 省略服務 */ ... 省略部分 } /*省略 catch*/ ... 省略部分 } } ``` ### 抽象 [SystemService](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/core/java/com/android/server/SystemService.java) 類 - 服務生命週期 * 這邊所提的 SystemService 是個 **抽象類** (請不要跟上一個搞混~ 雖然他們名子一樣),會讓其他系統的啟動類繼承 (eg. AMS#Lifecycle 類),跟系統的 SystemService 不同。 * SystemService 內部有多個參數,可以用來表示 **==服務啟動的過程==,相當於 ++服務啟動的一種生命週期++**,啟動說明請看註解 ```java= // /services/core/java/com/android/server/SystemService.java public abstract class SystemService { // 系統在啟動時的最早階段 public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // 異步啟動,等待 Sensor 服務 public static final int PHASE_WAIT_FOR_SENSOR_SERVICE = 200; // 可獲取鎖設置數據 public static final int PHASE_LOCK_SETTINGS_READY = 480; // 系統服務已準備好,可以安心調用核心服務 // eg. PowerManager or PackageManager public static final int PHASE_SYSTEM_SERVICES_READY = 500; // 可安心調用特定服務 public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; // 接收到這個啟動階段,服務可以廣播 Intent public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 可以綁定第三方應用 // 應用 APP 能將 Binder 調用到服務中 public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; // 啟動服務完成,可以跟用戶交互 public static final int PHASE_BOOT_COMPLETED = 1000; private final Context mContext; public SystemService(@NonNull Context context) { mContext = context; } public abstract void onStart(); ... 省略部分函數 } ``` ### SystemServiceManager 啟動服務 * 首先先來了解 SystemServiceManager 是如何啟動一個服務的 (**以下舉例 AMS 如何被啟動**) ```java= // /android/server/SystemServer.java // 啟動 AMS 的函數 private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { ... 省略部分 // Activity manager runs the show. // AMS 啟動,分析 startService 方法 ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); ... 省略部分 mActivityManagerService.setSystemProcess(); ... 省略部分 } ``` * Service 啟動流程,是透過 [**SystemServiceManager**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/SystemServiceManager.java)#startService 方法來啟動 1. **啟動 (服務) 類必須繼承抽象的 SystemService 類** (上面說的抽象類) 2. 呼叫 startService 時使用反射創建對象 (有 Context parameter 的建構函數) :::success * 呼叫 startService 再建構對象相當於一種延遲加載 ::: 3. 呼叫實現類的 **onStart 方法** (繼承抽象 SystemService 類) ```java= // SystemServiceManager.java // 快取 private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); ... // Create the service. // 1. 啟動類必須繼承 SystemService 類 if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { // 2. 啟動有 Context parameter 的建構函數 Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } /** * 省略 catch */ // 接著分析 startService 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 { // 呼叫實現類的 onStart 方法 // 抽象方法 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"); } ``` * UML 關係圖 > ![](https://i.imgur.com/xoKg0ul.png) ## Appendix & FAQ :::info ::: ###### tags: `Android Framework`