基於 AOSP 9.0 分析。java
開機大體會經歷以下幾個過程:android
SystemUI 啓動就是從 SystemServer 開始的。markdown
SystemServer 名爲系統服務進程,負責啓動 Android 系統的關鍵服務,其入口是 SystemServer.main():ide
public static void main(String[] args) {
new SystemServer().run();
}
複製代碼
能夠看到 main() 中生成了 SystemServer 對象並執行了 run 方法:ui
private void run() {
//省略部分代碼
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
//省略部分代碼
}
複製代碼
查看 startOtherServices():this
private void startOtherServices() {
//省略部分代碼
traceBeginAndSlog("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
traceEnd();
//省略部分代碼
}
static final void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
複製代碼
經過 intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService"))
啓動了服務 SystemUIService,進入 SystemUIService。spa
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
//省略其餘代碼
複製代碼
onCreate 方法中得到 SystemUIApplication 對象並調用其 startServicesIfNeeded 方法。3d
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
複製代碼
其中 config_systemUIServiceComponents 值在 AOSP/frameworks/base/packages/SystemUI/res/values/config.xml 裏:code
<string-array name="config_systemUIServiceComponents" translatable="false">
<!-- 對其餘模塊提供組件支持 -->
<item>com.android.systemui.Dependency</item>
<!-- NotificationChannel -->
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
<!-- 鎖屏模塊 -->
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<!-- 最近應用 -->
<item>com.android.systemui.recents.Recents</item>
<!-- 全局音量控制 -->
<item>com.android.systemui.volume.VolumeUI</item>
<!-- 分屏功能調節器 -->
<item>com.android.systemui.stackdivider.Divider</item>
<!-- 系統狀態欄,包括 StatusBar、NavigationBar、快捷菜單等等 -->
<item>com.android.systemui.SystemBars</item>
<!-- Storage 存儲通知 -->
<item>com.android.systemui.usb.StorageNotification</item>
<!-- 電量管理相關 -->
<item>com.android.systemui.power.PowerUI</item>
<!-- 鈴聲播放 -->
<item>com.android.systemui.media.RingtonePlayer</item>
<!-- 鍵盤相關 -->
<item>com.android.systemui.keyboard.KeyboardUI</item>
<!-- 畫中畫界面 -->
<item>com.android.systemui.pip.PipUI</item>
<!-- 快捷鍵調度程序 -->
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<!-- 截屏界面 -->
<item>com.android.systemui.ScreenDecorations</item>
<!-- 指紋相關 -->
<item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
複製代碼
繼續看 startServicesIfNeeded 方法:orm
private void startServicesIfNeeded(String[] services) {
if (mServicesStarted) {
return;
}
mServices = new SystemUI[services.length];
if (!mBootCompleted) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
mBootCompleted = true;
if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
Log.v(TAG, "Starting SystemUI services for user " +
Process.myUserHandle().getIdentifier() + ".");
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin("StartServices");
final int N = services.length;
for (int i = 0; i < N; i++) {
String clsName = services[i];
if (DEBUG) Log.d(TAG, "loading: " + clsName);
log.traceBegin("StartServices" + clsName);
long ti = System.currentTimeMillis();
Class cls;
try {
cls = Class.forName(clsName);
mServices[i] = (SystemUI) cls.newInstance();
} catch(ClassNotFoundException ex){
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
mServices[i].start();
log.traceEnd();
//省略其餘代碼
}
}
複製代碼
能夠看到 startServicesIfNeeded() 循環 start 了config_systemUIServiceComponents 裏的 Service,這裏的 Service 都是繼承了 SystemUI 類的子服務,後續將一一分析這些 Service。這樣,SystemUI 啓動流程分析完畢。
更多文章能夠關注公號 「吳小龍同窗」。