SystemUI属于系统级别的UI,是Android系统的核心应用,在开机过程中就会启动,负责反馈系统以及应用的状态,并与用户保持大量的交互。本系列文章涉及到的代码来自AndroidP版本。
为什么说SystemUI是在开机过程中启动的呢?
Init 是所有Linux程序的起点,而Android的启动过程都由Zygote产生。init 是 zygote的父进程, 而system_server和其他所有的com.xxx结尾的应用程序都是从zygote fork 而来。前面的SystemServer的启动过程不在涉猎范围之内,在此不做赘述,有兴趣的朋友可以从这里了解。
我们直接从SystemServer是如何启动SystemUI开始。先来一张时序图,能比较清晰完整的了解SystemUI的启动流程。
在./frameworks/base/services/java/com/android/server/SystemServer.java文件中,有个main方法:
public static void main(String[] args) {
new SystemServer().run();
}
main方法中启动了run(),在run中启动了一系列的服务,在SystemServer代码中,对系统的服务类别分为三类:BootstrapServices(包含ServiceManager,ActivityManagerService,PackageManagerService,DisplayManagerService,PowerManagerService, LightsService等),CoreServices(包含BatteryService,UsageStatsService,WebViewUpdateService等),OtherServices(包含ConnectivityService, NetworkManagementService, storageManager, WindowManagerService, AlarmManagerService, SystemUI等)
private void private void run() {
......
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();
}
......
}
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();
}
通过startServiceAsUser启动SystemUIService,并调用其onCreate方法。
./frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
......}
}
在onCreate方法中会调用SystemUIApplication中的startServicesIfNeeded方法,实际会调用startServicesIfNeeded(String),实例化SystemUI中的核心组件,并启动。
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
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");
}
}
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();
......
mServicesStarted = true;
}
./SystemUI/res/values/config.xml
- com.android.systemui.Dependency
- com.android.systemui.util.NotificationChannels
- com.android.systemui.statusbar.CommandQueue$CommandQueueStart
- com.android.systemui.keyguard.KeyguardViewMediator
- com.android.systemui.recents.Recents
- com.android.systemui.volume.VolumeUI
- com.android.systemui.stackdivider.Divider
- com.android.systemui.SystemBars
- com.android.systemui.usb.StorageNotification
- com.android.systemui.power.PowerUI
- com.android.systemui.media.RingtonePlayer
- com.android.systemui.keyboard.KeyboardUI
- com.android.systemui.pip.PipUI
- com.android.systemui.shortcut.ShortcutKeyDispatcher
- @string/config_systemUIVendorServiceComponent
- com.android.systemui.util.leak.GarbageMonitor$Service
- com.android.systemui.LatencyTester
- com.android.systemui.globalactions.GlobalActionsComponent
- com.android.systemui.ScreenDecorations
- com.android.systemui.fingerprint.FingerprintDialogImpl
- com.android.systemui.SliceBroadcastRelayHandler
startServicesIfNeeded方法遍历config_systemUIServiceComponents数组services[i],紧接着通过反射将其转化为具体类的对象,存在数组mServices[i]中 ,并调用start()方法依次启动对应组件,启动完成后会回调 onBootCompleted( ) 方法。mService[i] 里的值不同时,调用的每个组件中的 start() 方法也不相同。config_systemUIServiceComponents数组中包含了SystemUI中需要启动的组件,这些组件都是SystemUI的子类实现。在之后的文章中会逐一对各组件的启动和运行流程进行学习分析。