以Android 8.0代码,首先记载下SystemUI的启动过程。
1.SystemServer.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();
}
SystemServer中启动SystemUIService服务,位置在AMS准备工作完成后,可以在这里用来启动第三方的服务等等。
2.SystemUIService.onCreate
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
// For debugging RescueParty
if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
throw new RuntimeException();
}
}
getApplication()获取包含该服务的application,然后强制转化为SystemUIApplication,接着调用其startServicesIfNeeded方法。
3.SystemUIService.startServicesIfNeeded
public void startServicesIfNeeded() {
startServicesIfNeeded(SERVICES);
}
/**
* The classes of the stuff to start.
*/
private final Class<?>[] SERVICES = new Class[] {
Dependency.class,
NotificationChannels.class,
CommandQueue.CommandQueueStart.class,
KeyguardViewMediator.class,
Recents.class,
VolumeUI.class,
Divider.class,
SystemBars.class,
StorageNotification.class,
PowerUI.class,
RingtonePlayer.class,
KeyboardUI.class,
PipUI.class,
ShortcutKeyDispatcher.class,
VendorServices.class,
GarbageMonitor.Service.class,
LatencyTester.class,
GlobalActionsComponent.class,
};
- startServicesIfNeeded方法的参数是一个class的数组,涵盖了SystemUI里要启动的类,例如recent,keyboard,SystemBar等等都是我们在SystemUI界面非常熟悉的东西。
- 实际上这类class都继承于SystemUI.java,而SystemUI.java是一个抽象类,有点像我们熟知的工厂模式。主要是实现的方法是start()和onBootCompleted()方法。
4.SystemUIService.startServicesIfNeeded
private void startServicesIfNeeded(Class<?>[] services) {
if (mServicesStarted) {
return;
}
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() + ".");
final int N = services.length;
for (int i = 0; i < N; i++) {
Class<?> cl = services[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
try {
Object newService = SystemUIFactory.getInstance().createInstance(cl);
mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
} 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();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
Dependency.get(PluginManager.class).addPluginListener(
new PluginListener<OverlayPlugin>() {
private ArraySet<OverlayPlugin> mOverlays;
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
StatusBar statusBar = getComponent(StatusBar.class);
if (statusBar != null) {
plugin.setup(statusBar.getStatusBarWindow(),
statusBar.getNavigationBarView());
}
// Lazy init.
if (mOverlays == null) mOverlays = new ArraySet<>();
if (plugin.holdStatusBarOpen()) {
mOverlays.add(plugin);
Dependency.get(StatusBarWindowManager.class).setStateListener(b ->
mOverlays.forEach(o -> o.setCollapseDesired(b)));
Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
mOverlays.size() != 0);
}
}
@Override
public void onPluginDisconnected(OverlayPlugin plugin) {
mOverlays.remove(plugin);
Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
mOverlays.size() != 0);
}
}, OverlayPlugin.class, true /* Allow multiple plugins */);
mServicesStarted = true;
}
利用反射机制,依次获取Services里的各个class,并使用onstrat和onBootCompleted方法完成各个类的加载工作。
以上仅做一个SystemUI启动过程的一个初始流程,分布模块较多,后续分析。
网友评论