学习笔记:前面部分和 Android 10 一样。
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功能图:
SystemServer功能图.png
接着进入到 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<CoreStartable>> 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) 启动流程分析完毕。