Android笔记(十)Android O SystemUI启动流程

我们知道systemui属于系统级应用,在开机过程中就会启动。具体来讲是在SystemServer进程中startOtherService()方法来启动的。

startOtherService(){
...
startSystemUi(context,windowManagerf);
...
}

startSystemUi()方法中就是做了启动SystemUIService服务的操作

static final void startSystemUi()(Context context ,WMS,wm){
    Intent intent =  new Intent();
    intent.setComponent(new     ComponentName("com.android.systemui","com.android.systemui.SystemService"));
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    context.startServiceAsUser(intent,UserHandle.SYSTEM);
    wm.onSystemUiStarted();

值得注意的是,到这里为止,开启启动还没有完成,因为startOtherService()方法都还没有走完。所以暂时还不会发送ACTION_BOOT_COMPLETE广播,该广播是在AMS中的finishBooting()中发送的。(该广播在我们SystemUIService中有做监听,用来判断是否完成系统启动)。
回到SystemUI中,我们会进入到SystemUIService服务中,在onCreate()方法中调用

(SystemUIApplication)getApplication()).startServicesIfNeeded();

从而进入到SystemUIApplication中进行处理。至于为什么startService()后怎样走到Service的onCreate()方法中,后面会专门花一篇来讲解Service的启动(类似于Activity的启动,gityuan的博客有对4大组件启动做专门的讲解,这里暂不讨论)。

对于SystemUIApplication,我们先看onCreate()方法(在getApplication()之前SystemUIApplication就已经执行完了onCreate()方法,具体来说,在SystemUI进程起来的时候就会走到该进程Application中的onCreate()方法)。

setTheme(R.style.systemui_theme);
SystemUIFactory.createFromConfig(this);
if(Process.myUserHandle().equals(UserHandle.SYSTEM)){
    ...
    //注册ACTION_BOOT_COMPLATETED广播
    IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
    regitsterReceiver(new BroadCastReceiver()){
        public void onReceive(Context context,Intent intent){
            if(mBootCompleted) return;//如果系统以及完成启动,直接返回;
            unregisterReceiver(this);
            mBootCompleted = true;
            //如果service开启了,则执行onBootCompleted
            if(mServicesStarted){
                for(;;){
                    mServices[i].onBootCompleted();
                }
            }
        }
    },filter);
}

上面onRecevie()中的代码在系统完成启动之后执行,再看之前在SystemUIService中执行的

private void startServiceIfNeeded(class[] services){
    ...
    for(;;){
    通过反射的方式获取到相关service服务实例
        mServices[i].start();//启动服务,StatusBar状态栏服务对应的是SystemBars
    }
    ...
    mServiceStarted = true;
}

这样,流程就走到了SystemBars中的start()方法

createStatusBarFromConfig();

该方法再次通过反射的方式获取到StatusBar实例

private SystemUI mStatusBar;
cls = mContext.getClassLoader().loadClass("com.android.systemui.statusbar.phone.StatusBar");
mStatusBar = (SystemUI)cls.newInstance();//StatusBar继承自SystemUI,反射生成的为StatusBar类型对象,引用为SystemUI类型引用

这里,要注意的是SystemBars和StatusBar类都是继承自SystemUI,前者用于在systemui进程启动时和SystemUIApplication进行交互,并且包含一个SystemUI属性,用来指向一个StatusBar对象,并start()该对象。总结一下SystemBars的作用

  • 在SystemUIApplication中通过反射得到SystemBars实例
  • 通过反射得到StatusBar实例
  • start StatusBar实例,进入到状态栏

以上的所有准备工作完成后,接下来就到了我们状态栏加载阶段,这一过程从StatusBar.start()方法开始

//1.快捷面板控制类实例化,通知数据初始化
mXXXController = Dependency.get(xxx);
mNotificationData = new NotificationData();
//2.获取系统服务
mWindowManagerService = ...
mDevicePolicyManager = ...
mPowerManager = ...
//3.注册一系列ContentObserver
mContext.getContentResolver().registerContentObserver(...);
//4.获取StatusBarManagerService
mBarService = IStatusBarService.Stub.asInterface(SM.getService(string));
//5.获取CommandQueue实例,并作为参数注册到mBarService中,用来和StatusBarManagerService交互
mCommandQueue = ...
mBarService.registerStatusBar(mCommandQueue,,,,);
//6.创建Status Bar窗口
createAndAddWindows(); 
//7.注册NotificationListenerService
mNotificationListenerService.registerAsSystemService(,,,);
//8.一系列的广播监听...
...
//9.锁屏相关初始化
...

over

你可能感兴趣的:(andorid)