首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 8.0 SystemUI(三):一说顶部 StatusBar

Android 8.0 SystemUI(三):一说顶部 StatusBar

作者头像
菜天哥哥
发布2018-08-16 10:28:58
3.2K0
发布2018-08-16 10:28:58
举报
文章被收录于专栏:猿湿Xoong猿湿Xoong猿湿Xoong

前言

大家好,我是 ptt 。咱们继续 Android 8.0 SystemUI 的分析。

···

···

好吧,我承认很久没更新 SystemUI 的文章了,再次给大家道个歉。具体什么原因,可以看 上一篇文章 的最后。

不出意外,以后每周三会推一篇 SystemUI 的文章。有空余时间的话,其他时间也会发。

本文为 顶部StatusBar 的「第一说」,是的,有第一说就有第二说、第三说。目前是计划分三篇文章将 「顶部 StatusBar」相关逻辑大体讲完。

你没看错,是顶部 StatusBar。本来,按照T哥我的分法,SystemUI 的 StatusBar 是分为如下三步走的。起标题的话,也是起为StatusBar、Notification栏、QuickSettings。

而对于顶部 StatusBar,是打算一篇结束,分为四段:notification、statusIcon、signal集群、电池和时钟 各自的添加和更新。

但是,我发现 8.0 中顶部状态栏 notification icon 部分逻辑有了很大的改动。对比 7.0,多出了个NotificationInflater。并且,icon 和 expand 的逻辑流程是几乎相同的。

这就增加了分析 notification icon 相关流程的复杂度,虽然大概分析差不多了,但写出来很费时。

而对于signal信号群的添加与更新流程分析,也完全可以单拎出来搞一搞,或者和电池、时钟一起。

所以

  • 一说会讲讲顶部 StatusBar 的初始化、分块、StatusIcon 块的添加和更新。
  • 二说内容计划是信号群icon与电池、时钟相关内容
  • 三说将抖抖 notification icon 相关内容。

目录

老规矩,先上目录。

StatusBar组成

按照T哥的分法,顶部StatusBar由4个部分组成,看下图。

图 1.1

图 1.2

图 1.1 是我在 8.0 模拟器上截的图,图 1.2 是布局 status_bar.xml 的组成。将图1.1标识与图1.2 id 一一对应。

  1. 对应的是notification_icon_area,平日里显示的都是notifications,如三方和系统的一些通知。
  2. 对应的是statusIcons,平日里显示的一些系统状态,如蓝牙、闹铃等。
  3. 是信号集群,显示的是信号相关的view,如wifi,cell信号格等,对应的是signal_cluster_view.xml。
  4. 则是剩余的两个独立的图标, 分别为电池电量显示、时间显示。

StatusBar布局

那status_bar.xml这个布局又是如何被使用并加载的呢?

首先,让我们回顾一下 SystemUI 的启动流程:最终通过调用各自service组件的start方法,有序完成所有组件的初始化。SystemBars的start方法,通过读取strings中配置的类名,初始化对应的StatusBar组件。

在手机中,我们的StatusBar组件就是StatusBar.java。

要说status_bar.xml,不得不提的则是super_status_bar.xml。这个layout,一看名字就很super。它是整个status bar的 root 布局。它的加载流程如下:

StatusBar.java

-> start

-> createAndAddWindows

-> addStatusBarWindow

-> makeStatusBarView

-> inflateStatusBarWindow

变量mStatusBarWindow与其对应。它是一个StatusBarWindowView类,继承FrameLayout,负责整体框架上的排版和绘制,部分事件的监听及分发。

super_status_bar.xml 的布局主要包含以下部分。

其中的 id 为 status_bar_container 的布局,就是我们要找的对象。

当你再三的看这个id名的时候,相信你一定不陌生,xxx_container,没错,它也是个 FrameLayout。

平日里,我们使用 Fragment 都这么用。

果然,在 StatusBar 的 makeStatusBarView 方法中,status_bar_container 被替换为了一个Fragment。

这个CollapsedStatusBarFragment,只是一个container,包裹着几个部分。

在其onViewCreated中,加载了statusIcons布局。

我们要分析的 StatusIcon,在 Fragment 的 onViewCreated 中,开启了它罪恶的一生?不,它早已开启了罪恶的一生。

StatusIcon的初始化与更新

前面说了,StatusIcon块,主要负责的是系统状态的显示,比如蓝牙、闹铃、定位、省流量开关等。

这些Icon,都是系统预定好了是哪些。并在一个配置文件定义了slot,或者说是标签。如果你想加一个新类型图标,首先要修改的是这个文件中的config_statusBarIcons数组。

/frameworks/base/core/res/res/values/config.xml

那我们的 StatusBar 到底是如何初始化并更新这些Icon的?

根据 config_statusBarIcons这个id,仅仅发现了它在StatusBarIconControllerImpl 这个类中有被使用。而且是被传入父类构造方法中。

为了方便看清各类的关系,T哥一框一线画的类图送给你们。

其中:

1、Dependency 是SystemUI为了优化耦合依赖关系搞的类,在其start方法中,实例化了大量的Controller类,StatusBarIconContrllerImpl 在其中进行实例化。

2、StatusBar类 是 StatusBar 模块的核心类。

3、PhoneStatusBarPolicy 是负责StatusIcon的添加和更新,是StatusIcon初始化和更新的核心类

4、StatusBarIconContrllerImpl 是 StatusBarIconController 实现类,提供对IconGroup(即IconManager)的管理。

5、StatusBarIconList 是 StatusBarIconControllerImpl 的父类,保存所有 Status Icon 的 Slot 和对应的Icon。

6、IconManager 负责和View打交道。仔细的同学,应该记得StatusIcon罪恶一生开始地方那两行代码,有DarkIconManager,并将view传入了DarkIconManager。

在SystemUIApplication启动各路服务时,第一被启动的服务组件是Denpendency,为什么?因为在服务数组中它排第一。

在Dependency的start方法中,实例化了impl类,故而根据配置初始化了icon的slot。

在StatusBar的start方法中, 待初始化完毕,实例化PhoneStatusBarPolicy。

PhoneStatusBarPolicy的构造方法,完成所有了StatusIcon的初始化和状态监听。

并在有相关图标状态发生改变后,调用impl的setIcon方法,判断后,进行更新操作。

在IconManager中,尤其是DarkIconManager,通过将生成的StatusBarIconView add to 或 remove from ViewGroup 或 设置 visible,完成 icon 的 显示与隐藏。

以下是 T哥一框一线画的时序图,送给你们。

最后

源码讲解本身就不容易,又是以微信公众号的方式进行, 故而T哥将代码部分能省则省,不能省的,都是用图来代替。

希望能提高你们的阅读质量。

但是,我是依据阅读分析源码写出的这篇文章,读者们理应边看源码边阅读,方能收获最大。

Android 6.0 - 7.0 - 8.0 每个版本的 StatusIcon 框架都有所改变,如果能看看之前版本,理解会更为深刻。

--- End ---

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 菜天 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档