systemui

2023-11-15

 

一、SystemUI 概述

二、模块基本布局

三、模块内部框架

四、模块流程

五、重要文件的介绍

 

 

一、SystemUI 概述

1.Statusbar 的功能作用

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

   1.2 状态栏的日期显示

2.Statusbar 的使用方法

    2.1 notification 的使用

    2.2 系统图标的增加删除

 

* notification 的使用

 

 

Notification n = new Notification();  //实例化Notification       

n.icon = R.drawable.icon; //设置状态栏显示图标

n.tickerText = "Test Notifaction";  //设置显示提示信息

n.when = System.currentTimeMillis(); //显示时间

n.flags = Notification.FLAG_NO_CLEAR;  

n.flags = Notification.FLAG_ONGOING_EVENT;   

static final int ID = 1;

NotificationManager nm =(NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);  

 

Intent intent = new Intent(Main.this, Main.class);  

PendingIntent pi = PendingIntent.getActivity(Main.this,0, intent, 0);  

n.setLatestEventInfo(Main.this, "My Title","My Content", pi);  

nm.notify(ID, n); //发出通知  

nm.cancel(ID);   //取消通知

 

 

 

如何区分“正在进行的”和“通知”,谁决定一个事件是“正在进行的”还是持续的“通知”?

通过设置Notification的flag属性可以设定notification是正在进行的还是持续的notification。FLAG_INSISTENT和FLAG_ONGOING_EVENT标志位可以让Notification成为持续的或正在进行的Notification。

正在进行的事件的通知:

notification.flags =notification.flags | Notification.FLAG_ONGOING_EVENT;

持续的Notification一直重复,直到用户取消:

notification.flags =notification.flags | Notification.FLAG_INSISTENT;

 

* 系统图标的增加删除

 

状态栏添加显示的系统图标的步骤

1.frameworks\base\core\res\res\drawalbe中添加系统图标的图片资源

2.frameworks\base\core\res\res\values\config.xml 中添加图片引用,这些 icon 在这个stringarray的位置就决定了其在status bar 上显示的位置了。

3.在 StatusbarPolicy.java 中初始化所增加的系统图标

4.在构造函数中 SetIcon

5.StatusBarPolicy 调用registerReceiver注册了感兴趣的 intent,当感兴趣的 intent 发生时,对图标进行更新

6..添加图标更新函数

删除时删除相关代码图片即可

 

二、模块基本布局

 

1.StatusBar的布局文件:frameworks/base/packages/SystemUI/res/layout/status_bar.xml

2.LinearLayoutandroid:id="@+id/icons"我们看到的状态栏,系统默认是左边放通知图标 notificationIcons,右边放状态图标 statusIcons :

  --通知图标区域:IconMerger android:id="@+id/notificationIcons"

  --状态图标区域:LinearLayout android:id="@+id/statusIcons"

  --时间图标区域:com.android.systemui.statusbar.Clock

3.LinearLayoutandroid:id="@+id/ticker"显示。在正常情况下ticker 是不显示的,只有在 StatusBarService收到通知时它才显示

4.最后一个是DateView ,它是在点击statusbar时才显示的,默认是隐藏的

5.StatusBar的下拉布局文件:frameworks/base/packages/SystemUI/res/layout/

status_bar_expanded.xml

 

三、模块内部框架

 

 

 

Statusbar内部各种交互以及模块与其他应用的交互都是建立在StatusbarService之上的,其中包括Statusbar 视图的创建(包括 Statusbar 、 TrackingView和 StatusbarExpandedView),视图动画,系统图标(闹钟、 wifi 、SIM卡等)的加载和管理,其他应用通知信息的加载显示、更新、删除等,其他应用的远程接口控制(如当打电话时statusbar处于禁用状态的)对Android系统其他应用的通知信息(包括图标、 tracker 、notification的布局等)的处理。SIM 卡信息的控制等。

总之StatusbarService是 Statusbar 的灵魂所在,是 Statusbar的核心,所有关于Statusbar 的操作处理都是建立在 StatusbarService 这个基础之上的。

StatusbarService所在目录:\frameworks\base\packages\SystemUI\src\com\android\systemui\

statusbar\StatusBarService.java

 

四、 模块流程

 

 

1.启动流程

   1.1 StatusbarService的启动流程

   1.2 系统图标初始化流程

2.通知处理

3.图标更新

   2.1 通过广播接收器的方式

   2.2 通过远程代理方式

4.拖动刷新

5.远程接口

 

1.启动流程

 

1.1 StatusbarService的启动流程

 

1.当系统进程system_press启动之后,调用系统SystemServer.java,在SystemServer 中运行 ServerThread.run()方法时会注册 StatusBarManagerService:

statusBar = newStatusBarManagerService(context);   

ServiceManager.addService(Context.STATUS_BAR_SERVICE,statusBar);

2.让后调用StatusBarManagerService的systemReady2() 方法,会在systemReady2() 方法中启动StatusbarService:

ComponentName cn =ComponentName.unflattenFromString(mContext.getString(com.android.internal.R.string.config_statusBarComponent));  

Intent intent = new Intent(); 

intent.setComponent(cn);

mContext.startService(intent); 

3.在SystemUI模块的SystemUiApp.java的onCreate方法中也会startService,这是当Statusbar意外退出而导致StatusbarService停止服务时会重新启动StatusbarService

 

1.2 系统图标初始化流程

 

在启动StatusBarService后,StatusbarService会调用一个makeStatusBarView的方法,在里面将创建StatusBarView,

在创建StatusbarView的过程中会加载系统图标。

在启动StatusbarService的过程中会创建StatusBarPolicy的对象,StatusBarPolicy.java主要负责状态栏显示策略的管理(如状态栏的图标什么时候显示,在什么位置显示等)。StatusBarPolicy的构造函数中初始化了很多系统图标(如电池信息图标,闹钟图标,声音图标,信号栏图标等)。默认时有很多图标是不显示的,需要显示时再进行更新。

以电池电量显示为例,大概关键步骤如下:

1.通过BroadcastReceiver机制,StatusBarPolicy中注册的             mIntentReceiver收到BatteryService广播的   ACTION_BATTERY_CHANGED事件触发;

2.调用updateBattery(intent)开始更新电池状态栏;

3.从intent中解析需要的字段,调用StatusBarManager的setIcon();     (StatusBarManager是客户端使用的状态栏管理类)

4.通过IBinder机制跨进程调用StatusBarManagerService的setIcon();     (StatusBarManagerService派生于IStatusBarService.Stub,是状态栏管理的服务端,是具体实现,StatusBarManagerService有一个mIcons成员,这个list成员在StatusBarManagerService创建时加载。StatusBarManagerService的setIcon()过程中,会又"battery"字段获得在mIcons中的索引,再由包名、图片id和等级创建StatusBarIcon实例,并将这个实例更新StatusBarIconList中所获得索引对应项)

5.调用CommandQueue的setIcon();

(CommandQueue派生于IStatusBar.Stub,有一个内部接口Callbacks,这个接口的实现就是StatusBarService。CommandQueue、StatusBarService和StatusBarManager属于同一个进程,而StatusBarManagerService是一个系统级服务,它们之间必然需要通过IBinder进程间通信。CommandQueue用于处理状态栏、通知相关的请求,内部维护了一个事件队列,setIcon()会创建一个OP_SET_ICON的massege,发送给Handler处理(CommandQueue内部也有一个StatusBarIconList实例,这个实例是由StatusBarService创建。在处理OP_SET_ICON的massege前,会先通过getViewIndex获得图标View的位置索引viewIndex,(因为有些图标有可能为空)再更新StatusBarIconList,最后调用Callbacks,也就是StatusBarService的addIcon()或者updateIcon());

6.以addIcon()为例,StatusBarService的addIcon()会创建一个新的StatusBarIconView,将第步中所创建的StatusBarIcon实例设置进去,然后把这个view添加到LinearLayout的viewIndex位置。

这样一个电池相关图标就在状态栏上添加或者更新了。

 

2.通知处理

 

 

在应用Activity中实现通知栏图标变化的程序中,是用NotificationManager对象mNotificationManager来发送通知。

1.通知为Notification mNotification  对象,填充mNotification  的图标和消息内容以及一个when;

2.然后构造了一个Intent对象intent,包含了本Activity对象的引用,以及本Activity的类名,一个PendingIntentpi对象,包含上述Intent对象以及本Activity对象的引用,是用于消息列表中显示本Activity项。

3.点击时重新激活Activity,然后调用nm.setLatestEventInfo设置状态栏下拉列表项内容;

4.最后调用nm.notify(1,n)方法来发送通知。

接着改变状态栏的工作就由NotificationManager和StatusBarManagerService交互了。

 

 

 

3.图标更新

   2.1 通过广播接收器的方式

 

StatusBarPolicy调用registerReceiver注册了感兴趣的 intent, 当感兴趣的intent 发生时,对图标进行更新。例如,设置一个闹钟后,闹钟模块会发出一个叫做Intent.ACTION_ALARM_CHANGED 的广播,然后 StatusBarPolicy接收到此广播,继而更新状态栏上的闹钟图标。

代码示例:

// Alarm clockStatusBarPolicy构造方法中初始化闹钟图标

mService.setIcon("alarm_clock",R.drawable.stat_notify_alarm,0);

mService.setIconVisibility("alarm_clock",false);

// StatusBarPolicy构造方法中注册闹钟改变广播

filter.addAction(Intent.ACTION_ALARM_CHANGED);

//改变闹钟图标

private final void updateAlarm(Intentintent) {

boolean alarmSet =intent.getBooleanExtra(“alarmSet”, false);

mService.setIconVisibility(“alarm_clock”,alarmSet);

}

 

   2.2 通过远程代理方式

 

 

StatusBarManager有一个更新图标的方法: publicvoid updateIcon(IBinder key, String slot, int iconId, int iconLevel),不过StatusBarManager 并未把方法公开在 sdk 中,但是应该有方法可以访问的。

      public voidupdateIcon(IBinder key, String slot, int iconId, int iconLevel) {

            try {

                mService.updateIcon(key, slot,mContext.getPackageName(), iconId,                                                                                 iconLevel);

            } catch (RemoteException ex) {

                       throw newRuntimeException(ex);

            }

      }

mService 是StatusBarManager的一个成员变量,StatusBarManager 被构建的时候被赋值,他是 IStatusBar 的一个代理对象

     StatusBarManager(Contextcontext) {

           mContext = context;

           mService =IStatusBar.Stub.asInterface(

                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));

     }

 

4.拖动刷新

 

 

从点击StatusBar会出现新的View,它的流程如下:

StatusBarView 就是StatusBar 所代表的View,那么查看它的代码,看它处理点击的方法。

它属性变量保存了StatusBarService的引用mService,它的点击处理函数onTouchEvent()和onInterceptTouchEvent()都会调用到StatusBarService类中的interceptTouchEvent()方法。

当我们点击StatusBar 时,会先走到onInterceptTouchEvent()这个函数,而且这个函数只会在第一次走到,然后会走到onTouchEvent() 方法,这个方法每收到一个TouchEvent() 就会走到,因此会走到多次。

函数onInterceptTouchEvent() 的处理:

1 、调用到StatusBarService中的interceptTouchEvent() ,在这里又会走到event.getAction() == MotionEvent.ACTION_DOWN分支,在分支中,由于mExpanded == false 且y < hitSize会继续调用prepareTracking(y) 。

2 、函数prepareTracking()处理:这里由于mExpanded == false所以会向H 中发送MSG_ANIMATE_REVEAL 消息,进入StatusBarService自己的消息循环。执行doRevealAnimation() 函数。

3 、函数doRevealAnimation()处理:这个实现的功能很简单,就是在TrackingView( 就是点击时StatusBar 下出现的View)还没有完全显示出来的时候,通过动画的方式,一点一点的将TrackingView 显示出来。

当我们手指离开时调用顺序如下:

1 、StatusBarView :onTouchEvent(),此时Action != MotionEvent.ACTION_DOWN 走到 StatusBarService :interceptTouchEvent();

2 、interceptTouchEvent() 中会走到分支elseif (mTracking) ;

3 、由于ACTION_UP所以会调用performFling(),在这里会向Handler 发送 MSG_ANIMATE消息,然后进入函数doAnimation() 。

4 、在doAnimation() 由于mAnimY <mStatusBarView.getHeight() 分支成立,会继续调用updateExpandedViewPos(0)和performCollapse();

5 、在performCollapse()中,通过mTrackingView.setVisibility(View.GONE)实现了让mTrackingView的隐藏,其实这个函数还实现了其他的View 的隐藏,比如我们点击后进行拖动所出现的其他View 。

 

5.远程接口

 

StatusBarManagerService通过使用 IStatusBar 的 aidl调用CommandQueue 在 CommandQueue 中定义Callbacks

StatusBarService实现了 CommandQueue 中 Callbacks的回调

public interface Callbacks {

public void addIcon(String slot, int index, intviewIndex, StatusBarIcon icon);

public void updateIcon(String slot, int index, intviewIndex,

                                     StatusBarIcon old, StatusBarIcon icon);

public void removeIcon(String slot, int index, intviewIndex);

public void addNotification(IBinder key,StatusBarNotification notification);

public void updateNotification(IBinder key,StatusBarNotification notification);

public void removeNotification(IBinder key);

public void disable(int state);

public void animateExpand();

public void animateExpandToggles(booleanneedForceStatusBar);

public void animateCollapse();

public void showSIMIndicator(String businessType);

public void hideSIMIndicator();

}

 

五、重要文件的介绍

 

 

1.StatusBarManagerService是服务端StatusBarService的管理者 

2.StatusBarservice是Statusbar 的核心

3.StatusBarPolicy负责状态栏显示的策略管理

4.CommandQueue是StatusBarservice 和

   StatusBarManagerService 交互的枢纽

StatusBarManagerService是服务端StatusBarService的管理者  

                 

 frameworks\base\services\java\com\android\server\

        StatusBarManagerService.java

StatusBarManagerService是StatusBarService的管理者,是StatusBarService与外界通信的桥梁,在 StatusBarManagerService.java中,有 addNotification, removeNotification,updateNotification等方法用于管理传递给他的通知对象。这个类是一些管理方法,实际执行相关动作的是在IStatusBar.java里面,这个是framework/base/core/java/com /android/internal/statusbar/IStatusBar.aidl自动生成的用于IPC 的类。

StatusBarservice是Statusbar 的核心

\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\StatusBarService.java

StatusBarService这个服务是Statusbar模块的中心点,所有关于图标的加载、更新、删除等处理,与应用的交互,对通知信息的处理,动画的完成等都是建立在StatusBarService这个基础之上的。

StatusBarPolicy负责状态栏显示的策略管理

\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\StatusBarPolicy.java

Android中状态栏上有很多图标,这些图标什么时候显示什么时候不显示,这些都是StatusBarPolicy来管理的。StatusBarPolicy的构造函数里初始化了好几个图标,如闹钟icon,信号栏icon等。默认时有很多图标是不显示的,需要显示时再进行更新。StatusBarPolicy调用registerReceiver注册了感兴趣的intent,当感兴趣的intent发生时,对图标进行更新。StatusBarPolicy只是一个策略管理,实际的功能是StatusBarService来实现的。StatusBarService初始化时初始化了一个用于显示statusbar的StatusBarView。StatusBarView里面定义了icon名字,的显示顺序,对应的png图等,在StatusBarService调用makeStatusBarView方法时实现statusbar的初始化。

CommandQueue是StatusBarservice 和

StatusBarManagerService交互的枢纽

\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\

CommandQueue.java

IStatusBar.java里面对应的方法是用CommandQueue 的接口callback 的形式调用的,callback的实现在对应的服务提供类也就是StatusBarService.java中提供的。最终执行状态栏更新通知等事件都是在实现的CommandQueue.Callbacks里面执行。

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

systemui 的相关文章

随机推荐

  • MySQL第一讲:MySQL索引规范

    索引 Index 是帮助MySQL高效获取数据的数据结构 数据库系统维护着满足特定查找算法的数据结构 这些数据结构以某种方式引用 指向 数据 这样就可以在这些数据结构上实现高级查找算法 这种数据结构 就是索引 文章目录 1 类型 三种 2
  • C# Contains、Replace和Trim的用法

    Contains 方法用于判断字符串中是否包含指定的字符或字符串 如果包含指定的字符或字符串返回 true 否则返回 false 例如 String str ABCDE str1 ABC str2 GGG str contains str1
  • Kaggle入门赛-Digit Recognizer(手写数字识别)

    文章目录 1 数据处理与可视化 2 模型搭建与训练 3 模型预测结果 4 代码整合 Kaggle入门赛 手写数字识别所使用的数据集MNIST是计算机视觉上的 Hello world 数据集 这个经典的手写图像数据集一直作为基准分类算法的基础
  • pythonssl双向认证_Python 上的 ssl 提示验证失败,有什么办法深究具体失败的原因么?...

    错误提示是这样 Traceback most recent call last File line 1 in File usr lib python2 7 ssl py line 1007 in get server certificate
  • 技术管理- 怎样做好技术规划?

    1 前言 随着团队的人数的提高与成员的技术水平不断提高 同时业务的发展也对团队 个人提出了更高的要求 所以也要不断向技术方向进行努力探索 动如一人 是我们始终坚持的团队理念 个人能力强弱并不能决定整个团队的研发效率水平 只有大家都有了体系化
  • 7-21 求特殊方程的正整数解 (15分)

    本题要求对任意给定的正整数N 求方程X2 Y2 N的全部正整数解 输入格式 输入在一行中给出正整数N 10000 输出格式 输出方程X2 Y2 N的全部正整数解 其中X Y 每组解占1行 两数字间以1空格分隔 按X的递增顺序输出 如果没有解
  • kafka踩坑——java找不到kafka-run-class.sh: line 309: exec: java: not found

    今天执行 user 1 test 1 opt kafka sudo bin zookeeper server start sh config zookeeper properties opt kafka bin kafka run clas
  • Spring Boot应用篇-JSR参数校验定制

    Spring Boot应用篇 JSR参数校验定制 T1 前言 SpringBoot中默认提供了对JSR Java Specification Requests 注解的校验支持 但并没有对校验失败抛出的异常进行处理 该博文主要介绍个人对Spr
  • 解决Android Studio安装过程中“SDK tools directory is missing”的问题

    SDK tools directory is missing 这是因为安装时你的计算机无法连接到google的服务器 对google服务器的域名地址解析出问题了 无法从google服务器下载SDK tools 安装时自动跳过安装SDK to
  • switch语句格式_JavaScript流程控制语句_if语句(十一)

    目录 什么是流程控制语句 if语句的格式以及使用 一 什么是流程控制语句 JavaScript中的语句是从上到下一层一层执行的 通过流程控制语句可以控制程序执行的流程 使程序可以根据一定的条件来选择执行 使用条件判断语句可以在执行某个语句之
  • 华为云构建docker服务流程

    最近买了一个华为云服务器 配置不高适合学习 今天就从0开始从这个华为云服务器搭建我们自己的一个docker服务 安装docker 步骤1 更新系统软件包 sudo yum update 步骤2 添加docker存储库 sudo yum co
  • 前端开发工具DevTools的详细知识点总结(一)

    文章目录 打开DevTools 元素面板 Style面板 Computed面板 devtools取色器 控制台面板 基本功能介绍 控制台应用 网络面板 功能区介绍 分析请求 结语 打开DevTools devtools 即Chrome 开发
  • 《Java 并发编程实战》--读书笔记

    Java 并发编程实战 注 极客时间 Java 并发编程实战 读书笔记 GitHub https github com ByrsH Reading notes blob master Concurrency Java并发编程实战 极客时间
  • TYPE-C接口引脚详解

    Type C口有4对TX RX分线 2对USBD D 一对SBU 2个CC 另外还有4个VBUS和4个地线 1 当Type C接口仅用作传输DP信号时 则可利用4对TX RX 从而实现4Lane传输 这种模式称为DPonly模式 2 Typ
  • MFC之MessageBox、AfxMessageBox用法

    在软件中我们经常会弹出个小窗口 给一点点提示 这就会用到消息对话框 在Win32 API程序中只有MessageBox这一种用法 而在MFC中就有三各方法 1 调用API中的MessageBox 2 调用CWnd的成员函数MessageBo
  • PYQT5中QT Designer设置界面、按钮等背景图

    超级简单的新手教程 目录 文章目录 第一步 第二步 第三步 第一步 制作一个 qrc文件 在
  • python使用Axes3D画三维图加入legend图例时报错AttributeError: ‘Poly3DCollection‘ object has no attribute ‘_edgecolo

    Q python使用Axes3D画三维图加入legend图例时报错AttributeError Poly3DCollection object has no attribute edgecolors2d 报错源代码 fig plt figu
  • 计算机网络和因特网的基本认识

    计算机网络和因特网 笔者阅读 计算机网络 自顶向下方法 第七版第一章所作笔记如下 主要为计算机网络和因特网的基本认识 第一章概述笔记入口 第二章应用层笔记入口 第三章运输层笔记入口 第四章网络层数据平面笔记入口 1 什么是因特网 1 1 因
  • Git教程:标签

    实际上看到这边 对于Git分支仓库这些概念以及commit push pull等操作 但是有些东西我们可能常见到 但是不怎么经常用的 tag 标签其实就算一个 我们下载一些开源项目的时候 在GitHub上经常看到版本 有的项目是通过tag来
  • systemui

    一 SystemUI 概述 二 模块基本布局 三 模块内部框架 四 模块流程 五 重要文件的介绍 一 SystemUI 概述 1 Statusbar 的功能作用 1 1 状态栏的通知功能 包括时间 通知 系统状态等 1 2 状态栏的日期显示