SystemUI是在SystemServer中启动的。
SystemServer
//SystemServer.java
private void startOtherServices() {
//...
try {
statusBar = new StatusBarManagerService(context, wm);//启动StatusBarManagerService
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
reportWtf("starting StatusBarManagerService", e);
}
//...
mActivityManagerService.systemReady(() -> {
//...
try {
startSystemUi(context, windowManagerF);//启动SystemUI
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
//...
}, BOOT_TIMINGS_TRACE_LOG);
}
private static 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);//启动SystemUIService
windowManager.onSystemUiStarted();
}
SystemServer在startOtherServices方法中创建StatusBarManagerService并注册到ServiceManager中,然后调用AMS的systemReady方法,传入一个Runnable回调,在Runnable中调用了startSystemUi方法,启动了SystemUIService。
StatusBarManagerService实现了IStatusBarService这个AIDL接口,用于外部调用状态栏和导航栏。
SystemUIService
//SystemUIService.java
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
//...
}
SystemUIService创建时调用了SystemUIApplication的startServicesIfNeeded方法。
SystemUIApplication
//SystemUIApplication.java
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);//从配置中读取SystemUI类信息
startServicesIfNeeded(names);
}
private void startServicesIfNeeded(String[] services) {
if (mServicesStarted) {
return;
}
mServices = new SystemUI[services.length];//创建数组存放SystemUI
//...
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);
Object o = cls.newInstance();//反射创建对象
if (o instanceof SystemUI.Injector) {
o = ((SystemUI.Injector) o).apply(this);
}
mServices[i] = (SystemUI) o;//放入数组
} 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();//调用SystemUI的start方法进行初始化
log.traceEnd();
//...
if (mBootCompleted) {
mServices[i].onBootCompleted();//调用SystemUI的onBootCompleted方法
}
}
//...
mServicesStarted = true;
}
SystemUIApplication通过配置文件读取SystemUI的类信息,然后通过反射创建SystemUI对象,并调用它的start方法和onBootCompleted方法,SystemUI通过start方法进行初始化,自此,SystemUI的通用启动流程完毕。
SystemBars
SystemBars是一个SystemUI对象,在上面的流程中进行初始化,它的启动实际上是为了启动StatusBar。
//SystemBars.java
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
createStatusBarFromConfig();
}
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
final String clsName = mContext.getString(R.string.config_statusBarComponent);//配置中读取StatusBar的类信息
if (clsName == null || clsName.length() == 0) {
throw andLog("No status bar component configured", null);
}
Class> cls = null;
try {
cls = mContext.getClassLoader().loadClass(clsName);//获取Class对象
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
mStatusBar = (SystemUI) cls.newInstance();//反射创建StatusBar
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
if (mStatusBar instanceof StatusBar) {
SystemUIFactory.getInstance().getRootComponent()
.getStatusBarInjector()
.createStatusBar((StatusBar) mStatusBar);
}
mStatusBar.start();//调用StatusBar的start方法
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
StatusBar
StatusBar也是SystemUI对象,但它并没有在SystemUIApplication中直接创建,而是通过SystemBars创建。
//StatusBar.java
@Override
public void start() {
//...
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));//获取IStatusBarService代理对象
mRecents = getComponent(Recents.class);
// Connect in to the status bar manager service
mCommandQueue = getComponent(CommandQueue.class);
mCommandQueue.addCallback(this);//StatusBar实现了CommandQueue.Callbacks接口,将StatusBar加入CommandQueue
RegisterStatusBarResult result = null;
try {
result = mBarService.registerStatusBar(mCommandQueue);//将CommandQueue注册到IStatusBarService,并获取保存在IStatusBarService中的信息
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
createAndAddWindows(result);//创建状态栏与导航栏
//根据获取到的信息进行初始化
setSystemUiVisibility(mDisplayId, result.mSystemUiVisibility,
result.mFullscreenStackSysUiVisibility, result.mDockedStackSysUiVisibility,
0xffffffff, result.mFullscreenStackBounds, result.mDockedStackBounds,
result.mNavbarColorManagedByIme);
// StatusBarManagerService has a back up of IME token and it's restored here.
setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis,
result.mImeBackDisposition, result.mShowImeSwitcher);
// Set up the initial icon state
int numIcons = result.mIcons.size();
for (int i = 0; i < numIcons; i++) {
mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));//设置图标
}
//...
}
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
makeStatusBarView(result);
mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());//添加到WindowManager
}
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
//...
inflateStatusBarWindow(context);//inflate StatusBar布局
//...
createNavigationBar(result);//创建导航栏
}
自此,状态栏加载完成。