Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard ,电源界面 PowerUI,近期任务界面 Recent Task 等等。对于用户而言,SystemUI 的改动是最能直观感觉到的。所以,每一个 Android 版本在 SystemUI 上都有比较大的改动。而对开发者而言,理解 Android SystemUI 对优化Android系统界面,改善用户体验十分重要。java
在 Andorid 系统源码中,package/apps下放的是系统内置的一些 app,例如 settings,camera,Phone,Message 等等。而在 Framework/base/package 下,它们也是系统的 app,SystemUI 就在此目录下。它控制着整个Android系统的界面,但其实他也是一个 app,不一样于通常的 app,它不可卸载也不能够被第三方应用替换。android
这是 SystemUI 相关类的继承关系图,能够看到 SystemUI 为基类,每一个子类实现了不一样的系统界面。数组
先找到 framework/base/service/java/com/android/server/SystemServer.java 文件,里面有个main()方法,main 方法以下:app
public static void main(String[] args){ new SystemServer().run() }
main 方法里启动了 run() 方法,而在 run 方法中调用了 startBootstrapServices() 方法和 startOtherServices() 方法,在 startOtherServices() 里 mActivityManagerService.systemReady 建立线程去执行startSystemUi(context),这里将启动 SystemUI。具体方法以下:ide
而后咱们进入设置启动 systemui 程序的 SystemUIService 文件里,该文件在framework/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java.咱们看该文件的onCreate() 方法。方法以下:布局
能够看到有一句 ((SystemUIApplication) getApplication()).startServicesIfNeeded(),这句很关键,咱们再进入 startServicesIfNeeded(),看看具体是如何启动系统服务的。该方法以下:优化
其中有一个 for 循环,循环里第一句就是将 service[i] 赋值给 cl, 那么service里存的是什么呢?找到 service[i] 的赋值以下:ui
看到这里咱们就明白了,这里是拿到每一个和 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() 方法:spa
这里调用了 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启动流程图: