看完这一篇文章,彻底明白Android 8.0 SystemUI的启动流程

前言

上周去深圳后海OPPO面试,面试framework相关的岗位,面试官看到我的简历里面写有关一个SystemUI的项目,问了很多相关的问题,比如SystemUI的启动流程、通知模块的流程原理等等。SystemUI的启动流程其实之前有看过源码,但是面试回答的时候没有回答的很详细,可能还是准备不足,今天这篇博客也详细记录一下SystemUI 在Android源码中的启动流程吧。本篇博客代码基于Android 8.0,其他Android 版本也适用。

一、SystemServer 启动服务

相关源码:frameworks/base/services/java/com/android/server/SystemServer.java

systemserver里面回启动很多Android的系统服务,我们看看他的启动入口main函数里面执行了run方法,这个方法很长,但是
这个方法最重要的是startBootstrapServicesstartCoreServicesstartOtherServices 这三个方法。

   /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
    ...
    ...
    private void run() {
     ...
        startBootstrapServices();
        startCoreServices();
        startOtherServices()
     ...   
   }

这里
startBootstrapServices() 主要用于启动系统Boot级服务,AMS也是在这里被启动的。
startCoreServices() 主要用于启动系统核心的服务,比如BatteryService、WebViewUpdateService等等。
startOtherServices() 主要用于启动一些非紧要或者是非需要及时启动的服务。

二、startOtherServices 做了哪些事情

startOtherServices启动了很多服务,比如下列的这些网络、输入、窗口等服务。

    private void startOtherServices() {
        final Context context = mSystemContext;
        VibratorService vibrator = null;
        IStorageManager storageManager = null;
        NetworkManagementService networkManagement = null;
        NetworkStatsService networkStats = null;
        NetworkPolicyManagerService networkPolicy = null;
        ConnectivityService connectivity = null;
        NetworkScoreService networkScore = null;
        NsdService serviceDiscovery= null;
        WindowManagerService wm = null;
        SerialService serial = null;
        NetworkTimeUpdateService networkTimeUpdater = null;
        CommonTimeManagementService commonTimeMgmtService = null;
        InputManagerService inputManager = null;
        TelephonyRegistry telephonyRegistry = null;
        ConsumerIrService consumerIr = null;
        MmsServiceBroker mmsService = null;
        HardwarePropertiesManagerService hardwarePropertiesService = null;

这里面我们看到ststemUI的启动服务:

            try {
                startSystemUi(context, windowManagerF);
            } catch (Throwable e) {
                reportWtf("starting System UI", e);
            }

我们看看startSystemUi 做了哪些事情,原来是通过包名、类名启动systemUI 的服务。

    static final void startSystemUi(Context context, WindowManagerService windowManager) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

总结一下SystemServer中启动SystemUI服务的调用流程是:SystemServer().main-->SystemServer().run()-->startOtherServices()-->startSystemUi() 接下来我们看看"com.android.systemui.SystemUIService"这个service

二、SystemUI的内部启动流程

相关源码:frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

首先我们看看SystemUIService.java,在onCreate中执行了startServicesIfNeeded

@Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        // For debugging RescueParty
        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
            throw new RuntimeException();
        }

源生的systemUI服务里面有这些模块

    private final Class<?>[] SERVICES = new Class[] {
            Dependency.class,
            NotificationChannels.class,
            CommandQueue.CommandQueueStart.class,
            KeyguardViewMediator.class,
            Recents.class,
            VolumeUI.class,
            Divider.class,
            SystemBars.class,
            StorageNotification.class,
            PowerUI.class,
            RingtonePlayer.class,
            KeyboardUI.class,
            PipUI.class,
            ShortcutKeyDispatcher.class,
            VendorServices.class,
            GarbageMonitor.Service.class,
            LatencyTester.class,
            GlobalActionsComponent.class,
            RoundedCorners.class,
    };

startServicesIfNeeded 方法中会依次启动这些服务。

    private void startServicesIfNeeded(Class<?>[] services) {
        if (mServicesStarted) {
            return;
        }

        if (!mBootCompleted) {
            // check to see if maybe it was already completed long before we began
            // see ActivityManagerService.finishBooting()
            if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
                mBootCompleted = true;
                if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
            }
        }

        Log.v(TAG, "Starting SystemUI services for user " +
                Process.myUserHandle().getIdentifier() + ".");
        TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
                Trace.TRACE_TAG_APP);
        log.traceBegin("StartServices");
        final int N = services.length;
        for (int i = 0; i < N; i++) {
            Class<?> cl = services[i];
            if (DEBUG) Log.d(TAG, "loading: " + cl);
            log.traceBegin("StartServices" + cl.getSimpleName());
            long ti = System.currentTimeMillis();
            try {

                Object newService = SystemUIFactory.getInstance().createInstance(cl);
                mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }

            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start();
            log.traceEnd();

            // Warn if initialization of component takes too long
            ti = System.currentTimeMillis() - ti;
            if (ti > 1000) {
                Log.w(TAG, "Initialization of " + cl.getName() + " took " + ti + " ms");
            }
            if (mBootCompleted) {
                mServices[i].onBootCompleted();
            }
        }
        log.traceEnd();
        Dependency.get(PluginManager.class).addPluginListener(
                new PluginListener<OverlayPlugin>() {
                    private ArraySet<OverlayPlugin> mOverlays;

                    @Override
                    public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
                        StatusBar statusBar = getComponent(StatusBar.class);
                        if (statusBar != null) {
                            plugin.setup(statusBar.getStatusBarWindow(),
                                    statusBar.getNavigationBarView());
                        }
                        // Lazy init.
                        if (mOverlays == null) mOverlays = new ArraySet<>();
                        if (plugin.holdStatusBarOpen()) {
                            mOverlays.add(plugin);
                            Dependency.get(StatusBarWindowManager.class).setStateListener(b ->
                                    mOverlays.forEach(o -> o.setCollapseDesired(b)));
                            Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
                                    mOverlays.size() != 0);

                        }
                    }

                    @Override
                    public void onPluginDisconnected(OverlayPlugin plugin) {
                        mOverlays.remove(plugin);
                        Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
                                mOverlays.size() != 0);
                    }
                }, OverlayPlugin.class, true /* Allow multiple plugins */);

        mServicesStarted = true;
    }

到这里SystemUI 的启动就分析完了,下一篇博客分析一下Notification通知。

发布了78 篇原创文章 · 获赞 45 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/An_Times/article/details/90642944