Android状态栏介绍

课程纲要

 

1.整体功能介绍及操作说明

2.启动流程

3.  整体架构图

4.功能模块具体介绍

5.模块的框架原理以及类图和每个类的功能

6.对外接口使用以及外部接口


1.整体功能介绍及操作说明

 android2.2 开始 , 原本存在与 framework-res.apk 中的状态栏和下拉通知栏界面控制被分割出一个单独的 apk文件 , 命名为 SystemUI.apk保存在 System/priv-app 文件夹中。在 SystemUI.apk  , 保存着状态栏的图标 ,xml文件和控制文件等 

状态栏主要用来显示一些系统图标,应用的通知图标和系统时间。 状态栏模块就是控制和管理着这些图标,以及通知信息的显示和一些系统开关。

 

Ⅰ、状态栏的通知功能(包括时间,通知,系统状态等)

状态栏可与系统其它应用进行交互来显示在屏幕上方状态栏中的信息,并且 状态栏还可通过图标的显示变化来反应一些系统状态的变换,如电池电量, wifi ,蓝牙,闹钟等。状态栏 是一种让你的应用程序或系统信息变化在不使用 Activity 的情况下给用户的提醒和通知。

Ⅱ、状态栏的日期显示

状态栏也会显示系统时间,当前日期也会在状态栏显示,只是在默认情况下,日期是隐藏的,只有在下拉状态栏时才会显示,下图是L平台的日期显示。

2.启动流程

首先我们从SystemUIAndroidManifest文件可以发现:整个SystemUI是由"SystemUIService"这个服务启动的,而"SystemUIService"这个服务是在SystemServer.java通过startSystemUi方法进行启动的。

接下来,SystemUIService类执行自己的onCreate()方法,这个方法中首先要判断当前要启动的是手机的statusbar service,还是平板的statusbar service。判断结束后,代码调用是mServices[i].start()方法,即调用SystemUI类的Start()方法;SystemUI类又是被BaseStatusBar类实现的;PhoneStatusBar类又继承了BaseStatusBar类,重写了start()方法,因此实际调用的是PhoneStatusBarstart()方法来完成状态栏的启动。

3.状态栏整体架构图

android中,状态栏不属于某个应用程序,而是系统的一部分,是通过StatusBarService来管理维护的,整个模块的位置:framework/base/packages/SystemUI

要研究状态栏,首先我们从状态栏的布局文件入手来研究它的整体层次结构,文件位置:framework/base/packages/SystemUI/res/layout//status_bar.xml(sim卡布局)

根据布局文件,我们画出结构图,对状态栏有一个整体的了解

状态栏顶层的view一般分为两部分:状态栏静止显示的图标和收到通知以后动态显示的图标。

静止显示的图标又分为两部分:状态栏左侧的状态图标和状态栏右侧的静态图标,状态图标一般是不显示,只有在一定条件下才会显示,比如说是状态栏接收到通知等等,才会出现;而静态图标,一般情况下只要打开系统的一些开关,系统的时间,电池电量图标等等,它都是会显示。

要说到动态显示的图标,最常见的,比如说导入导出联系人等等,你都会看到状态栏上出现的图标与文字的切换等等。

状态栏下拉界面 view 布局:
 
下拉状态栏 view 显示,这个最主要的显示便是通知的具体显示了,不论系统的通知,第三方应用的通知都会在该界面以图标加文字的形式显示出来 另外还有 个专门显示快捷开关的界面。

根据状态栏的整体功能结构,我们将状态栏整体划分为以下三大模块

文字描述每个层次的功能说明,以及每一个层次的模块功能说明,并说明各个模块之间的交互关系:
如上 图, 状态栏按结构功能主要分为以上三部分。 

(1) 通知模块:显示系统发出通知的内容,有图标和文字的简短显示。

(2) 静态图标显示模块:系统设备的当前状态,例如打开了WIFI,蓝牙,闹钟,静音模式或是震动模式后,此区域都会显示相对应的图标

(3) 快捷开关模块这一块专门给该功能分配了一个panel进行显示。

     快捷开关的打开,都会显示在状态栏的静态图标对应区域,状态栏收到通知后也会在状态栏的左侧区域进行显示。

4.模块功能具体介绍

通知 (Notification) 的介绍:

 包括通知概要 通知标题 通知内容 通知图标 通知时间

快捷开关的作用

如上图所示为快捷开关的显示效果,总共9,从左至右依次为:

亮度调节,Wifi开关,蓝牙开关,移动数据开关,飞行模式开关,屏幕旋转开关手电筒开关,位置开关,情景模式所有的这些开关在设置界面都可以进行相应的设置,但是快捷开关的设计使得这些功能的启用和关闭更加快捷

sim卡信号显示刷新

如上图所示,为状态栏中的双sim卡显示,它都是与wifi的布局绑定在一起的。SIM卡信号一般包含:信号强度、数据类型(包含数据连接的图标标识)、网络类型等

5.模块的框架原理以及类图和每个类的功能

状态栏主要包含通知的显示加载,Sim卡信号的显示,快捷开关的显示以及状态栏中图标的更新,下面主要从这四个方面对状态栏做一个详细的说明:

    i)通知的显示:

主要类的作用说明:

PhoneStatusBar类路径:

framework/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar类为SystemUIService服务启动的第一个类,主要用于状态栏View的绘制及相应布局的加载,例如,状态栏的整体布局,sim卡布局,快捷开关布局,状态图标的布局等都是在该类的view绘制方法中进行初始化的。

BaseStatusBar类路径:

framework/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/

BaseStatusBarPhoneStatusBar的父类,继承了SystemUI抽象类,实现了CommandQueue.Callbacks接口中的方法,例如通知的更新方法,图标的更新方法等,都是在这个类中实现的。

StatsubarManagerService类路径:

framework/base/services/java/com/android/server

是一个系统级服务,这个类是一个IBinder的实现类,是systemui的业务实现类。

CommandQueue:

framework/base/packages/SystemUI/src/com/android/systemui/statusbar/

派生于IStatusBar.Stub,有一个内部接口Callbacks,这个接口的实现就是StatusBarService,用于处理状态栏、通知相关的请求,内部维护了一个事件队列,添加通知的方法会创建一个MSG_ADD_NOTIFICATIONmassege

发送给进行Handler处理,CommandQueueStatusBarServiceStatusBarManager属于同一个进程,而StatusBarManagerService是一个系统级服务,它们之间必然需要通过IBinder进程间通信。

NotificationManagerService类:

framework/base/services/java/com/android/server/

该类是由INotificationManager.Stub派生出来的,它实现了INotificationManager接口中定义的相关方法并向外部提供服务的类。主要向外提供enqueueNotificationWithTag()方法。该方法实际上是调用enqueueNotificationInternal(),他里面提供了对通知的发送上限,通知的声音播放,通知是否闪光等功能的具体处理。

NotificationManager类:framework/base/core/java/android/app/

该类主要是调用NotificationManagerService中的方法,例如通知的发送是调用NotificationManager中的notify方法,最终是调到NotificationManagerService中的enqueueNotificationInternal方法去做具体实现的。

ii)信号图标更新

状态栏信号主要指的是wifiSIM卡信号;根据不同机型SIM卡信号部分又分为单卡和多卡,多卡根据不同运营商要求又分为CT(电信)、CU(联通)、DEFAULT(默认)三种显示外观。

WifiSIM卡信号更新框架基本相同,简单的流程如下图:

按照以上所述信号更新的基本框图,首先状态栏需要加载承载信号显示的view,该view是在整个状态栏view初始绘制的时候加载,具体是在PhoneStatusBar类的注册对应的view。接着进入整个信号刷新类中MSimNetworkController,信号的实时刷新入口即是相应actionaction触发执行各信号信号值的确定,通过该类的 信号刷新方法调用接口传递信号值至图标显示更新类MSimSignalClusterView,并最终在此实现显示图标的更新。

单卡更新原理基本和多卡Dedalut模式相同,不同的是信号刷新类对应的是NetworkController;实际上多卡信号刷新类继承的也是NetworkController,因而其中原理基本一致。

iii)状态栏图标显示,更新

PhonesStatusBarPolicy类路径:

framework/base/packages/SystemUI/com/android/systemui/statusbar/phone/

该类主要注册了一个广播接收器,接收闹钟,数据同步,蓝牙,声音,sim卡状态等状态改变时发过来的广播,改变状态栏上对应的图标显示。

1 )通过广播机制,StatusBarPolicy中注册的广播接收器收BatteryService广播的电池状态改变的事件触发;

2 )调用StatusBarPolicy类中对应的更新方法开始更新状态栏中对应的图标显示。

3 )intent中解析需要的字段,调用StatusBarManager的设置图标的方法。StatusBarManager是客户端使用的状态栏管理类

4)通过IBinder机制跨进程调用StatusBarManagerService的设置图标的方法。StatusBarManagerService派生于IStatusBarService.Stub,是状态栏管理的服务端,是具体实现;

5) StatusBarManagerService有一个StatusBarIconList成员,这个list成员在StatusBarManagerService创建时,从配置文件中加载生成。StatusBarManagerService的设置图标的过程中,又会从配置文件中获取对应字段在StatusBarIconList中的索引,再由包名、图片id,创建StatusBarIcon实例,并根据StatusBarIconList中所获得索引对应项更新该实例。

6)调用CommandQueue的设置图标的方法。 CommandQueue用于处理状态栏、通知相关的请求,内部维护了一个事件队列,此时会创建一个设置图标的消息,发送给Handler进行处理;

7) CommandQueue内部也有一个StatusBarIconList实例,这个实例是由StatusBarService创建。在处理设置图标的消息之前,会先通过获得图标索引的方法获得图标的位置索引,再更新StatusBarIconList,最后调用Callbacks,也就是StatusBarService的添加图标的方法进行添加或者更新图标的方法进行更新。

iv)快捷开关显示,更新

首先PhoneStatusBarmakeStatusBarView方法中,首先创建一个QuickSetting类,这个类主要用于创建和显示这16种开关,原生代码中已经添加了相应的代码处理,但是大多数是用开关控制的,所以我们只有打开开关才会将其显示出来。这里我们要特别关注QuickSettingsContainerView这个类,它主要的作用就是让整个快捷开关在其上面加载,所以是必不可少的。最后就是通过QuickSetting类的setUp方法真正去创建快捷开关,这个方法是和sim卡的数量,蓝牙的状态,位置信息的状态,以及电池电量的状态都有关,所以提前需加载以及更新好其当前的状态图标。

6.对外接口使用以及外部接口

通知显示是在状态栏的BaseStatusBar类中进行处理的,它主要调用的外部接口就是IStatusBarService,该接口由StatusBarManagerService来实现,该类里边提供了将通知以一个键值对的形式存放在一个map集合中,键为一个IBinder对象,值为一个StatusBarNotification对象,后续的通知显示就是从该map集合中取出来的。

通知的管理类是NotificationManagerService,该类是由INotificationManager.Stub派生出来的,它是用来实现接口INotificationManager中定义的相关方法并向外部提供服务的类,它里面提供了通知的具体处理方法,主要由NotificationManager调用。

状态栏对外提供的接口为IStatusBar,它的实现类为CommandQueue,该类中提供了添加通知,更新通知以及删除通知的相应方法,该方法会发送其相应的消息给handler, 最后调用Callbacks接口中的对应方法,也就是StatusBarService对通知进行处理的方法。

状态栏图标的添加,刷新与通知的调用流程是一样的,只是其中调用的方法是图标对应的方法。

信号更新中主要使用了MSimNetworkController.MSimSignalCluster,该接口中定义了三个方法:

    1.用于实现wifi状态值的显示更新

    2.用于SIM卡信号的显示更新;

    3.用于飞行模式与信号更新的显示更新

接口实现类MSimSignalClusterView,该接口是衔接信号更新值和相应显示view的桥梁,通过接口的3个方法的实现最终将更新的信号值转化为对应的新状态图标显示出来。

                     

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值