AndroidQ SystemUI之启动

从本篇开始准备写一下关于SystemUI相关的东西,SystemUI包含的东西挺多的,顶部的StatusBar,中间的Lockscreen,底部的NavigationBar等等,可以说SystemUI就是一台手机的门面,是用户对手机系统的第一印象,非常重要

我们从SystemUI的启动开始分析,SystemUI作为一个系统Service,是在SystemServer中启动的

SystemServer.java

private void startOtherServices() {
	final WindowManagerService windowManagerF = wm;
	......
		traceBeginAndSlog("StartSystemUI");
           try {
               startSystemUi(context, windowManagerF);
            } catch (Throwable e) {
                reportWtf("starting System UI", e);
            }
	......
}
private static 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();
    }

我们可以看到,SystemUI这个service和系统普通的service启动方式一样,通过startServiceXXX,只不过它这里的用户是SYSTEM,我们看下它的intent,包名为
“com.android.systemui”,类名为"com.android.systemui.SystemUIService"。

SystemUIService.java

public class SystemUIService extends Service {
		@Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
		......
    }
}

SystemUIApplication.startServicesIfNeeded

 public void startServicesIfNeeded() {
        String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
        startServicesIfNeeded(names);
    }

首先加载了一个名为config_systemUIServiceComponentsarray,都是一些SystemUI的关键类,配置在config文件中

<string-array name="config_systemUIServiceComponents" translatable="false">
         <item>com.android.systemui.Dependency$DependencyCreator</item>
         <item>com.android.systemui.util.NotificationChannels</item>
         <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
         <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
         <item>com.android.systemui.recents.Recents</item>
         <item>com.android.systemui.volume.VolumeUI</item>
         <item>com.android.systemui.stackdivider.Divider</item>
         <item>com.android.systemui.SystemBars</item>
         <item>com.android.systemui.usb.StorageNotification</item>
         <item>com.android.systemui.power.PowerUI</item>
         <item>com.android.systemui.media.RingtonePlayer</item>
         <item>com.android.systemui.keyboard.KeyboardUI</item>
         <item>com.android.systemui.pip.PipUI</item>
         <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
         <item>@string/config_systemUIVendorServiceComponent</item>
         <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
         <item>com.android.systemui.LatencyTester</item>
         <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
         <item>com.android.systemui.ScreenDecorations</item>
         <item>com.android.systemui.biometrics.BiometricDialogImpl</item>
         <item>com.android.systemui.SliceBroadcastRelayHandler</item>
         <item>com.android.systemui.SizeCompatModeActivityController</item>
         <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
         <item>com.android.systemui.theme.ThemeOverlayController</item>
</string-array>

接着将获取到的string数组传入startServicesIfNeeded方法

startServicesIfNeeded(names)

private void startServicesIfNeeded(String[] services) {
		//如果SystemUI已经启动过了则不需要再启动
        if (mServicesStarted) {
            return;
        }
        //创建一个SystemUI类型的数组,用来存储services,这些services
        //都是继承SystemUI
        mServices = new SystemUI[services.length];
		
        final int N = services.length;
        //遍历services
        for (int i = 0; i < N; i++) {
            String clsName = services[i];
            long ti = System.currentTimeMillis();
            Class cls;
            try {
            	//通过类型获取其Class对象
                cls = Class.forName(clsName);
                //创建实际对象
                Object o = cls.newInstance();
                //如果services中有实现了SystemUI.Injector接口的类则
                //调用其apply方法,SystemUI.Injector继承自Function,
                //这是java8新增的函数式接口
                if (o instanceof SystemUI.Injector) {
                    o = ((SystemUI.Injector) o).apply(this);
                }
                //将创建的SystemUI的service添加到mServices数组
                mServices[i] = (SystemUI) o;
            } catch(ClassNotFoundException ex){
                throw new RuntimeException(ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }
            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
			//调用所有创建的类的start方法
            mServices[i].start();
            //监控启动SystemUI的耗时时间
            ti = System.currentTimeMillis() - ti;
            //单项启动超过1000ms则打印log
            if (ti > 1000) {
                Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
            }
            //系统启动完成则调用每个mServices的onBootCompleted方法
            if (mBootCompleted) {
                mServices[i].onBootCompleted();
            }
        }
       
        /*
		下面这一大段代码是SystemUI的插件化机制相关,本篇不分析
		*/
        ......
        mServicesStarted = true;
    }

其实SystemUI的启动挺简单的,就是依次调用config_systemUIServiceComponents这个config文件中定义的类的start方法和onBootCompleted方法,如果有SystemUI相关的问题可以直接在这个config文件中去找相关模块的类,从它们的start方法开始跟代码,我们在startServicesIfNeeded方法中省略了一大段关于SystemUI插件化的代码,这部分比较负责,我会在下一篇单独跟一下此部分代码流程。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值