美文网首页Android 源码浅析
Android 13 SystemUI 启动流程

Android 13 SystemUI 启动流程

作者: 孤街酒客0911 | 来源:发表于2023-03-06 10:46 被阅读0次

    学习笔记:前面部分和 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) 启动流程分析完毕。

    相关文章

      网友评论

        本文标题:Android 13 SystemUI 启动流程

        本文链接:https://www.haomeiwen.com/subject/qtepxdtx.html