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

相关文章
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
94 6
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
28 3
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
26 2
|
2月前
|
XML 前端开发 Android开发
Android View的绘制流程和原理详细解说
Android View的绘制流程和原理详细解说
44 3
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
19 0
|
3月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
55 4
|
3月前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
56 0
|
4月前
|
Android开发
我的Android进阶修炼:安卓启动流程之init(1)
本文深入分析了Android系统中的init进程,包括其源码结构、主要功能以及启动流程的详细注解,旨在帮助读者理解init作为用户空间的1号进程在Android启动过程中的关键作用。
84 1
|
3月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
157 0