Android 13 SystemUI 启动流程

简介: 学习笔记

学习笔记:前面部分和 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功能图:

26463879-b3489323b3037b61.png

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) 启动流程分析完毕。

相关文章
|
12天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
16天前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
26天前
|
测试技术 Android开发 开发者
【03】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第三篇安卓APP上架华为商店后面的步骤-华为应用商店相对比较麻烦一些-华为商店安卓上架
【03】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第三篇安卓APP上架华为商店后面的步骤-华为应用商店相对比较麻烦一些-华为商店安卓上架
|
4月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
108 6
|
4月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
4月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
39 3
|
4月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
37 2
|
4月前
|
XML 前端开发 Android开发
Android View的绘制流程和原理详细解说
Android View的绘制流程和原理详细解说
67 3
|
4月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
28 0
|
5月前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
80 0

热门文章

最新文章