具体分析(以下代码示例,讲解,都是通过,Android9代码来举例)
SystemUI,其实是可以看作是一个系统级的服务,也就是SystemUIService,
SystemUI的服务启动,要从SystemServer.run()方法入手
-
main 方法里启动了 run() 方法,而在 run 方法中调用了startOtherServices() 方法,在启动startOtherServices()时,会调用ActivityManagerService的systemReady方法。
private void run() {
省略
try {
startBootstrapServices();//启动引导服务
startCoreServices();//启动核心服务
startOtherServices();//启动其他服务
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
省略
}
-
在这个systemReady()方法里面,进行了startSystemUI(context,windowManagerF)的调用,通过Intent的方式,启动了SystemUIService
-
根据SystemUIService来看,这是一个系统的服务
-
在SystemUIApplication类中,查看startServiceIfNeeded(),该类会遍历Services数组,启动里面的所有服务systemui 相关的服务。
-
这个数组里面定义了很多的组件,这些都是SystemUI将要启动的,其中SystemBars就是我们今天要关注的服务,因为Android系统的状态栏和导航栏就是在这里面启动的。
- com.android.systemui.Dependency 是为了创建全局可用的依赖关系。
- com.android.systemui.SystemBars创建整个SystemUI视图的入口类。
- com.android.systemui.recents.Recents 最近任务
- com.android.systemui.volume.VolumeUI 音量控制
- com.android.systemui.pip.PipUI 画中画
- com.android.systemui.statusbar.CommandQueue 是一个 Binder 类,它会被StatusBar注册到 StatusBarManagerService 中,用于接收StatusBarManagerService服务端的消息。
-
继续看SystemUIApplication的startServicesIfNeeded(String[] services)方法,其中有一个 for 循环,循环里第一句就是将 service[i] 赋值给 clsName, 而service[i]的赋值就是各个SystemUI组件的具体类对象路径,这里通过反射的方法,创建出来对应的SystemUI组件实例对象:
private void startServicesIfNeeded(String[] services) {
省略
mServices = new SystemUI[services.length];
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;
mServices[i].start();
ti = System.currentTimeMillis() - ti;
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
省略
mServicesStarted = true;
}
看到这里我们应该就明白了,这里是拿到每个和 SystemUI 组件相关的类的完整路径,存到了service[] 里,然后赋值给cls,紧接着通过反射将其转化为具体的类对象,存到了mService[i]数组里,最后对象调start() 方法启动相关类的服务,启动完成后,再调用该类的onBootCompleted( ) 方法。