史上最详细的Android系统SystemUI 启动过程详细解析

注:
原文来自我的CSDN博客:http://blog.csdn.net/foreverJQQ/article/details/76268404

Android 系统 SystemUI 介绍

Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard ,电源界面 PowerUI,近期任务界面 Recent Task 等等。对于用户而言,SystemUI 的改动是最能直观感受到的。因此,每个 Android 版本在 SystemUI 上都有比较大的改动。而对开发者而言,理解 Android SystemUI 对优化Android系统界面,改善用户体验十分重要。

SystemUI 在哪

在 Andorid 系统源码中,package/apps下放的是系统内置的一些 app,例如 settings,camera,Phone,Message 等等。而在 Framework/base/package 下,它们也是系统的 app,SystemUI 就在此目录下。它控制着整个Android系统的界面,但其实他也是一个 app,不同于一般的 app,它不可卸载也不可以被第三方应用替换。

SystemUI 整体结构

这里写图片描述

这是 SystemUI 相关类的继承关系图,可以看到 SystemUI 为基类,每个子类实现了不同的系统界面。

  • Status Bar 系统上方的状态栏
  • Navigator Bar 系统下方的导航栏
  • Keyguard 锁屏界面
  • PowerUI 电源界面
  • Recents Screen 近期任务界面
  • VolumeUI 音量调节对话框
  • Stack Divider 分屏功能调节器
  • PipUI 画中画界面
  • Screenshot 截屏界面
  • RingtonePlayer 铃声播放器界面
  • Settings Activity 系统设置中用到的一些界面,例如:NetworkOverLimitActivity,UsbDebuggingActivity等。
这里写图片描述

SystemUI的启动流程

先找到 framework/base/service/java/com/android/server/SystemServer.java 文件,里面有个main()方法,main 方法如下:

public static void main(String[] args){
    new SystemServer().run()
}

main 方法里启动了 run() 方法,而在 run 方法中调用了 startBootstrapServices() 方法和 startOtherServices() 方法,在 startOtherServices() 里 mActivityManagerService.systemReady 创建线程去执行startSystemUi(context),这里将启动 SystemUI。具体方法如下:

这里写图片描述

然后我们进入设置启动 systemui 程序的 SystemUIService 文件里,该文件在framework/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java.我们看该文件的onCreate() 方法。方法如下:

这里写图片描述

可以看到有一句 ((SystemUIApplication) getApplication()).startServicesIfNeeded(),这句很关键,我们再进入 startServicesIfNeeded(),看看具体是如何启动系统服务的。该方法如下:


这里写图片描述

其中有一个 for 循环,循环里第一句就是将 service[i] 赋值给 cl, 那么service里存的是什么呢?找到 service[i] 的赋值如下:

这里写图片描述

看到这里我们就明白了,这里是拿到每个和 SystemUI 相关的类的反射,存到了 service[] 里,然后赋值给cl,紧接着将通过反射将其转化为具体类的对象,存到了mService[i]数组里,最后对象调 start() 方法启动相关类的服务,启动完成后,回调 onBootCompleted( ) 方法。
mService[i] 里的值不同时,调用的 start() 方法也不相同,这里我们以S ystemBars 的 start() 为例,所以mService[i].start() 先认为是 SystemBars.start().
SystemBars.java 位于framework/base/packages/SystemUI/res/com/android/systemui/statusbar/SystemBars.java ,找到 start() 方法:


这里写图片描述

这里调用了 mServiceMonitor.start(),旁边注释说的很清楚如果服务没有启动的话就调用onNoService()方法,进入 onNoService() 方法,该方法就位于 start() 方法下方,可以看到方法中调用了CreateStatusBarFromConfig() 该方法如下:

这里写图片描述

从中可以知道,该方法中先读取 value/config.xml 文件中 config_statusBarComponent 的值,这里为:com.android.systemui.statusbar.phone.PhoneStatusBar,然后通过反射得到了 PhoneStatusBar 对象,最后的 mStartus.start() 也就等于 PhoneStatusBar.start(),进入该方法,会发现,里面调用了super.start(),也就是先执行了父类的 start() ,其父类为 BaseStatusBar,该类的star()方法较多,就不放出来了,我们看重点,找到里面有调用一个 createAndAddWindows(),该方法为抽象方法,则会调用它的子类的方法,这里也就是 PhoneStatusBar 的 createAndAddWindows()方法,如下:

这里写图片描述

createAndAddWindows() 里只调用了 addStaBarWindow() 方法,而在该方法里,调用了makeStartusBarView,看名字就知道该方法关键,意为构建statusBar视图。该方法很长,里面有inflateStatusBarWindow(),进入该方法,可以看到,这么一句:

这里写图片描述

然后,我们通过 super_status_bar.xml 的分析 SystemBars 的大致视图构成了,super_status_bar.xml 代码如下:

这里写图片描述

super_status_bar.xml
super_status_bar.xml 中 include 了一个名称为 status_bar 的布局文件
super_status_bar.xml*中 include 了一个名称为 status_bar_expanded 的布局文件
这里的 status_bar 便是系统状态栏的布局文件,status_bar_expanded 便是下拉的通知窗口的布局文件
上述 super_status_bar.xml 与如下视图对应:

这里写图片描述

PhoneStatusBarView 即为手机最上方的状态栏,主要用于显示系统状态,通知等,主要包括 notification icons 和 status bar icons。status_bar.xml 即对应状态栏的视图如下:

这里写图片描述

PanelHolder
PanelHolder是用户下拉 status bar 后得到的 view。它主要包含 QuickSettings 和 Notification panel 两个部分。
PanelHolder是一个继承自 FrameLayout的自定义 view,它的内容是通过 include status_bar_expanded.xml进行填充的。
PanelHolder的布局比较复杂,为了提高 view 的重用性大量的使用了 include 标签。
status_bar_expanded.xml 对应的视图:

这里写图片描述

KeyguardBouncer
KeyguardBouncer是锁屏解锁界面,根据用户设置的解锁方式不同,展示不同的解锁模式。
keyguard_bouncer.xml 对应的 KerguardBouncer 视图:

这里写图片描述

附:
SystemUI启动流程图:

这里写图片描述

这里写图片描述

参考文章
http://www.jianshu.com/p/0ab1279465fa
http://qiangbo.space/2017-05-09/AndroidAnatomy_SystemUI_Intro/
http://qiangbo.space/2017-06-04/AndroidAnatomy_SystemUI_Bar/
http://www.open-open.com/lib/view/open1494316049681.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,376评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 上师范的时候,三毛去世了。 爱了她很久,读了很多她的书,青春的血液里满是撒哈拉的沙漠,还为她写了些狂妄不羁的文字,...
    江兆勇Jon阅读 459评论 3 10
  • 即日起,每读完一遍,写一篇读后感,字数不限,只求及时记录感想,灵感。 从不同角度看书,未来每次看,可以有一个主要抓...
    李茂林_1063阅读 353评论 0 0
  • 7.7.9 对象串行化(序列化)1 对象也是一种在内存中存储的数据类型,他的寿命通常随着生成该对象的程序终止而终止...
    曹渊说创业阅读 396评论 0 0