Android 13.0 SystemUI 启动流程
1、手机开机后,Android系统首先会创建一个Zygote(核心进程)。
2、由Zygote启动SystemServer。
3、SystemServer会启动系统运行所需的众多核心服务和普通服务、以及一些应用及数据。例如:SystemUI 启动就是从 SystemServer 里启动的。
4、进入锁屏界面,开机完成。
SystemServer 中有一个 main()方法为系统服务的入口;
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
在SystemServer 中的 main()方法中,就一句代码生成 SystemServer 对象,执行run 方法。在run()方法里启动了各类服务;
private void run() {
//省略部分代码
// Start services.
try {
traceBeginAndSlog(“StartServices”);
startBootstrapServices();
startCoreServices();
startOtherServices(); // 在该方法里启动了 SystemUI的服务。
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e(“System”, “******************************");
Slog.e(“System”, " Failure starting system services”, ex);
throw ex;
} finally {
traceEnd();
}
//省略部分代码
}
private void startOtherServices() {
//省略部分代码
t.traceBegin(“StartSystemUI”);
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf(“starting System UI”, e);
}
t.traceEnd();
//省略部分代码
}
private static void startSystemUi(Context context, WindowManagerService windowManager) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
Intent intent = new Intent();
intent.setComponent(pm.getSystemUiServiceComponent());
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
// 启动 SystemUIService
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
SystemServer功能图:
接着进入到 SystemUIService 的onCreate()方法里:
@Override
public void onCreate() {
super.onCreate();
// Start all of SystemUI
// 调用 SystemUIApplication 的 startServicesIfNeeded() 方法。
((SystemUIApplication) getApplication()).startServicesIfNeeded();
// 省略部分代码...
}
接着看 SystemUIApplication 的 startServicesIfNeeded() 方法。
public void startServicesIfNeeded() {
final String vendorComponent = SystemUIFactory.getInstance()
.getVendorComponent(getResources());
// 对 startables 进行排序,以便我们获得确定性排序。
// TODO:使 start 幂等并要求 CoreStartable 的用户调用它
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
// 重点关注,这是与之前版本不一样的地方。
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents());
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}
这里的 sortedStartables 是一个Map,里面存放待启动的各种SystemUI服务。
上述代码中 SystemUIFactory.getInstance().getStartableComponents() 我们一起来看看,如何获取的:
//SystemUIFactory.java
public class SystemUIFactory {
// 省略部分代码…
/**
* Returns the list of {@link CoreStartable} components that should be started per user.
*/
public Map<Class<?>, Provider<CoreStartable>> getStartableComponents() {
return mSysUIComponent.getStartables(); //这里将会返回要启动的组件列表
}
// 省略部分代码…
}
接着将会进入到 SysUIComponent.java中:
@SysUISingleton
@Subcomponent(modules = {
DefaultComponentBinder.class,
DependencyProvider.class,
SystemUIBinder.class,
SystemUIModule.class,
SystemUICoreStartableModule.class,
ReferenceSystemUIModule.class})
public interface SysUIComponent {
// 省略部分代码......
/**
* Returns {@link CoreStartable}s that should be started with the application.
*/
Map<Class<?>, Provider<CoreStartable>> getStartables();
// 省略部分代码......
}
这里使用了dagger的 @IntoMap注入相关类。只要是 继承 CoreStartable(之前版本的SystemUI) 类的都将会被注入。
注入方法,例如:
/** Inject into PowerUI. */
@Binds
@IntoMap
@ClassKey(PowerUI::class)
abstract fun bindPowerUI(sysui: PowerUI): CoreStartable
这里相关类就注入结束了,接着回到 SystemUIApplication 的 startServicesIfNeeded() 方法
private void startServicesIfNeeded(
Map<Class<?>, Provider> startables,
String metricsPrefix,
String vendorComponent) {
if (mServicesStarted) {
return;
}
mServices = new CoreStartable[startables.size() + (vendorComponent == null ? 0 : 1)];
if (!mBootCompleteCache.isBootComplete()) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
mBootCompleteCache.setBootComplete();
if (DEBUG) {
Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
}
mDumpManager = mSysUIComponent.createDumpManager();
Log.v(TAG, "Starting SystemUI services for user " +
Process.myUserHandle().getIdentifier() + ".");
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin(metricsPrefix);
int i = 0;
for (Map.Entry<Class<?>, Provider<CoreStartable>> entry : startables.entrySet()) {
String clsName = entry.getKey().getName(); // 获取类名
int j = i; // Copied to make lambda happy.
timeInitialization(
clsName,
() -> mServices[j] = startStartable(clsName, entry.getValue()), // 跟进去会发现,这里就和之前版本一样,调用start()方法启动对应服务。
log,
metricsPrefix);
i++;
}
// 省略部分代码......
log.traceEnd();
mServicesStarted = true;
FeatureOptions.sShouldShowUI = true;
}
到此 CoreStartable (SystemUI) 启动流程分析完毕。