systemUI之statusBar

SystemUI StatusBar流程梳理 SystemUI之StatusBar状态栏 布局结构 下拉菜单、状态栏都是属于statusbar,结构树上也是属于顶层的super_status_bar.xml(StatusBarWindowView) 从上图可以看出顶层树是super_status_bar,之后会走两个分支status_bar_container和status_bar_expanded。 status_bar_expanded下拉菜单,分快捷图标和通知栏。 status_bar_container状态栏.. 阅读详情

systemUI之statusbar

         看标题应该能猜出来这会是一个系列,不管写的咋样,就当是小结吧。因为是第一篇,所以会先说下systemUI是嘛,然后从view的角度认识一下systemUI的各个部件,重点分析一下statusbar的布局结构;最后是statusbar的加载流程。

一,文件目录

systemUI相对锁屏什么的它算是很规矩了,标准的android工程,安静的待在:

.\frameworks\base\packages\SystemUI目录下,可以直接单编译成apk,注意要push到system/app下面重启验证效果。


二,视图部件

 

 上面的图简单的表示了systemUI的结构,其实这个从我们的代码目录也可以知道个大概,那么啥是systemUI,干嘛独独要把这些放在一起弄个番号呢?个人本着细心学习,大胆推测的精神得到以下证据:1,它们都非常勤快,至少都是赶在launcher前面打卡;2不知疲倦,常驻内存,随时可以响应用户的使唤.有这些共性说它们是一奶同胞也就有论据了,如果你够耐心看下去会发现确实都是由一个systemUI服务孵化的。

因为该文的主角是statusbar,所以我们多花些笔墨解析一下它。statusbar在手机上其实分两个view:StatusBar和StatusBarExpanded,就拿StatusBar作典型进行分析吧:

从上面的层次图可以看出icon和ticker是两个平行frameLayout,一般时候都是icon布局显示,当有notification进来时ticker显示,为了方便研究分别给它们加了background color:


三,statusbar启动流程

我们知道了statusbar是啥,混了个脸熟后就可以对它的生平以及来龙去脉考究一番。为了描述方便,我试着把一个连贯的过程分成以下四步:

1,  systemUI是个服务

看一个android工程我们都会从AndroidManifest.xml文件开始分析,这个也不例外。从manifest文件中我们找到SystemUIService这个重要的服务,整个systemUI就是由它而起。通过简单的find命令,在systemserver.java里面找到了SystemUIService的启动代码。

2,  systemServer相关

systemServer的水其实非常深,它起于Zygote,负责Android系统所有的service注册登记,生和死。系统的分析需要另起篇幅,这里我们使用查找直接找到systemUIService的启动代码:


3,  systemUIservice

接上面,我们直接看onCreate方法,主要作用就是根据机器硬件配置决定是实例化statusbar还是systembar。并启动相应的start方法。

public void onCreate() {
        // Pick status bar or system bar.
	    //1.aidl远程调用windowmanager实例
        IWindowManager wm = IWindowManager.Stub.asInterface(
                ServiceManager.getService(Context.WINDOW_SERVICE));
        try {
		//2.在PhoneWindowManager里面进行判定是phone还是tablet或其他。
            SERVICES[0] = wm.canStatusBarHide()
                    ? R.string.config_statusBarComponent
                    : R.string.config_systemBarComponent;
        } catch (RemoteException e) {
            Slog.w(TAG, "Failing checking whether status bar can hide", e);
        }
		//3.实例化statusbar。
        final int N = SERVICES.length;
        mServices = new SystemUI[N];
        for (int i=0; i<N; i++) {
            Class cl = chooseClass(SERVICES[i]);
            Slog.d(TAG, "loading: " + cl);
            try {
                mServices[i] = (SystemUI)cl.newInstance();
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }
		//4.启动statusbar。
            mServices[i].mContext = this;
            Slog.d(TAG, "running: " + mServices[i]);
            mServices[i].start();
        }
    }

通过查看systemUI的资源文件找到以下定义

<!-- Component to be usedas the status bar service.  Mustimplement the IStatusBar
     interface. This name is in the ComponentName flattened format (package/class)  -->
    <string name="config_statusBarComponent"translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
 
    <!--Component to be used as the system bar service. Must implement the IStatusBar
     interface. This name is in the ComponentName flattened format (package/class)  -->
<string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>

所以实际上起的是PhoneStatusBar.java的start()。

4,PhoneStatusBar

前面的都是铺垫,到这里终于要来实际的了。分析的顺序是PhoneStatusBar.start() => StatusBar.start()=>PhoneStatusBar.makeStatusBarView()。

public void start() {
        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();
        mWindowManager = IWindowManager.Stub.asInterface(
                ServiceManager.getService(Context.WINDOW_SERVICE));
//调用父类statusBar的start方法。
 super.start();
//加载导航条。
        addNavigationBar();
        //addIntruderView();
        // 最后调用policy加载更新图标
        mIconPolicy = new PhoneStatusBarPolicy(mContext);
}

我们进入statusBar.start()一探究竟:

public void start(){
        // 1.First set up our views and stuff.
        View sb = makeStatusBarView();
 
        // 2.Connect in to the status bar manager service
       。。。。。。
        try {
            mBarService.registerStatusBar(mCommandQueue, iconList,notificationKeys, notifications,
                    switches, binders);
        } catch (RemoteException ex) {
        // 3.If the system process isn't there we're doomed anyway.
        }
        disable(switches[0]);
        setSystemUiVisibility(switches[1]);
        topAppWindowChanged(switches[2] != 0);
        // 4.StatusBarManagerService has a back up of IME token and it's restoredhere.
        setImeWindowStatus(binders.get(0),switches[3], switches[4]);
        setHardKeyboardStatus(switches[5] != 0,switches[6] != 0);
 
        // 5.Set up the initial icon state
        int N = iconList.size();
        int viewIndex = 0;
        for (int i=0; i<N; i++) {
            StatusBarIcon icon =iconList.getIcon(i);
            if (icon != null) {
                addIcon(iconList.getSlot(i), i,viewIndex, icon);
                viewIndex++;
            }
        }
 
        // 6.Set up the initial notification state
        N = notificationKeys.size();
        if (N == notifications.size()) {
            for (int i=0; i<N; i++) {
               addNotification(notificationKeys.get(i), notifications.get(i));
            }
        } else {
            Log.wtf(TAG, "Notification list length mismatch: keys=" + N
                    + " notifications=" +notifications.size());
        }
 
        // 7.Put up the view
        final int height = getStatusBarHeight();
 
        final WindowManager.LayoutParams lp = newWindowManager.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                height,
                WindowManager.LayoutParams.TYPE_STATUS_BAR,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    |WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                    |WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                PixelFormat.OPAQUE);
       
        // 8.the status bar should be in an overlay if possible
        final Display defaultDisplay
            = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();
        if (ActivityManager.isHighEndGfx(defaultDisplay)){
            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
        }
 
        lp.gravity = getStatusBarGravity();
        lp.setTitle("StatusBar");
        lp.packageName = mContext.getPackageName();
        lp.windowAnimations = R.style.Animation_StatusBar;
        WindowManagerImpl.getDefault().addView(sb,lp);
 
        if (SPEW) {
            Slog.d(TAG, "Added status bar view: gravity=0x" + Integer.toHexString(lp.gravity)
                   + " icons=" + iconList.size()
                   + " disabled=0x" + Integer.toHexString(switches[0])
                   + " lights=" + switches[1]
                   + " menu=" + switches[2]
                   + " imeButton=" + switches[3]
                   );
        }
 
        mDoNotDisturb = new DoNotDisturb(mContext);
}

statusBar乃至整个systemUI的view是怎么创建起来的,我们必须进入第一步的makeStatusBarView()方法细看一下。

protected View makeStatusBarView() {
     。。。。
//1.加载ExpandedView。
        ExpandedView expanded = (ExpandedView)View.inflate(context,
                R.layout.status_bar_expanded, null);
        if (DEBUG) {
            expanded.setBackgroundColor(0x6000FF80);
        }
        expanded.mService = this;
//2.加载PhoneStatusBarView。
        PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
                R.layout.status_bar, null);
        sb.mService = this;
        mStatusBarView = sb;
//3.决定是否加载NavigationBarView。
        try {
            boolean showNav = mWindowManager.hasNavigationBar();
            if (showNav) {
                mNavigationBarView = 
                    (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);

                mNavigationBarView.setDisabledFlags(mDisabled);
            }
        } catch (RemoteException ex) {
            // no window manager? good luck with that
        }
//4.加载statusBar的各个具体控件。
        // figure out which pixel-format to use for the status bar.
        mPixelFormat = PixelFormat.OPAQUE;
        mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
        mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
        mIcons = (LinearLayout)sb.findViewById(R.id.icons);
        mTickerView = sb.findViewById(R.id.ticker);
//4.实例化各种控制器。
        mLocationController = new LocationController(mContext); // will post a notification
        mBatteryController = new BatteryController(mContext);
        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
        mNetworkController = new NetworkController(mContext);
//5.加载并更新RecentsPanelView。
        // RecentsPanel
        mRecentTasksLoader = new RecentTasksLoader(context);
        updateRecentsPanel();
//6.注册定制的监听器。
        // receive broadcasts
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        context.registerReceiver(mBroadcastReceiver, filter);

        return sb;
    }

以上大概就是就是整个systemUI的加载流程,主线就是statusBar,在加载它的时候顺便也把RecentsPanel,NavigationBarView等看起来没啥联系的东西也一块加载好,私以为这里的代码结构还可以更好,4.1可能会有所改善吧。

小结:

         这些东西其实一个月前就想写了,断断续续的一直没有开始着手,一来总有很多琐事或看起来更重要的事来打扰,二来是总觉得自己看的肤浅,不敢写,也不想写。不过总算是写出第一篇了。systemUI这块是整个系统UI风格的关键也最大程度地影响着用户的日常体验,无论是优化还是现有的usb处理挂载流程都有很多东西值得去挖掘,日后陆续放出吧。

SystemUI StatusBar状态栏部分功能记录 目录 核心类: 部分界面布局文件 滑动和点击事件: 通知的通知显示过程 核心类: StatusBar.java 状态栏整体控制 StatusBarWindowView.java 状态栏未扩展时的跟布局 PhoneStatusBarView.java 继承PanelBar.java NotificationPanelView.java 状态栏下拉后的控制类,继承自Panel.................. 阅读详情

相关推荐

Android 4.0 ICS SystemUI浅析——StatusBar加载流程之Notification

前面三篇文章《Android 4.0 ICS SystemUI浅析——SystemUI启动流程》、《Android 4.0 ICS SystemUI浅析——StatusBar结构分析》、《Android 4.0 ICS SystemUI浅析——StatusBar加载流程分析》逐步分析了SystemUI中StatusBar的启动以及加载流程,本文主要分析StatusBar上的Notificati

Keep Awake,Keep Studying,Keep Moving,Keep... 1万+

Android SystemUI之StatusBar,状态栏(二)

systemui其实结构是比较复杂,里面管理各种服务,导航栏,状态栏,近期列表,下拉菜单,关机界面等,其中以导航栏和状态栏,近期列表用的比较多,也是本博文会重点讲解的内容。从结构上来讲下拉菜单和状态栏都是属于statusbar,结构树上也是属于顶层的super_status_bar.xml(StatusBarWindowView),说这么多还不如直接上图,这样大家看的比较清晰直观。

yangxiucheng520的博客 2583

SystemUI源码分析三(StatusBar的加载流程)

SystemServer中调用startsystemui函数启动SystemUIService,在SystemUIService的onCreate()函数中:((SystemUIApplication) getApplication()).startServicesIfNeeded();SystemBar继承SystemUI,因此被启动了。onStart()public void start(){

6721

SystemUI系列之StatusBar

在上一篇(https://blog.youkuaiyun.com/u011164827/article/details/102998091)分析到SystemUI的启动过程,现在分析StatusBar。 启动分析 SystemUI在SystemUIApplication会启动各个模块,在这个地方会调用com.android.systemui.SystemBars的start方法。 frameworks/...

一个小菜鸟的成长之路的专栏 1968

Android 8.0 SystemUI(三)——StatusBar

状态栏与导航栏的启动由StatusBar.start()完成 /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @Override public void start() { mNetworkController = Dependenc...

nidan1027的博客 2479

Android SystemUI——StatusBar状态栏构建(五)

通过前面的分析我们知道,SystemUI 的所有组件实例都是通过和 Dagger2 相关的 ComponentHelper 类得到的,该类中的 SystemUI 组件实例最初是通过 Dagger2 的依赖注入得到的,而 Dagger2 在实例化 SystemUI 组件的时候,会调用对应组件的构造方法。源码位置:/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java。

小旭的专栏 1165

systemUI之statusbar

systemUI之statusbar          看标题应该能猜出来这会是一个系列,不管写的咋样,就当是小结吧。因为是第一篇,所以会先说下systemUI是嘛,然后从view的角度认识一下systemUI的各个部件,重点分析一下statusbar的布局结构;最后是statusbar的加载流程。 一,文件目录 systemUI相对锁屏什么的它算是很规矩了,标准的android工程,安静的

创造晴天 1303

开源DIY | 打造会“听”会“走”的智能移动垃圾桶

本文详细介绍了如何利用Arduino和超声波传感器打造一款会“听”会“走”的智能移动垃圾桶。通过开源硬件和简单编程,实现声控移动和自动避障功能,适合创客爱好者和家庭DIY。项目成本控制在200元内,涵盖硬件搭建、电路连接和核心功能实现,是入门级机器人制作的理想选择。

weixin_33670713的博客 228

[深入SystemUI]-了解statusbar的启动流程

本文流程基于Android 9.0 1.启动SystemUIService 在SystemServer中有一个方法startSystemUi,当系统启动后,会执行到SystemServer的startSystemUi()方法,正是在这个方法中启动了SystemUIService。 static final void startSystemUi(Context context, WindowMa...

百吉猫的博客 866

NVIDIA Orin AGX开发环境搭建避坑指南:从Ubuntu 22.04到ROS2完整配置流程

本文详细介绍了NVIDIA Orin AGX开发环境搭建的全流程,从Ubuntu 22.04系统安装到ROS2深度优化,涵盖驱动部署、CUDA环境配置、散热与功耗管理等关键步骤。特别针对Orin AGX的特性提供了实用避坑指南和性能优化技巧,帮助开发者高效完成开发环境配置。

weixin_28340315的博客 450

Linux内存压力测试工具【memtester】详且精

对Linux下的压力测试工具memtester有一个比较人性化的概述,以及避坑心得。

weixin_44118923的博客 1万+

[深入SystemUI]-SystemUI_statusbar的启动流程

本文流程基于Android 9.0 1.启动SystemUIService 在SystemServer中有一个方法startSystemUi,当系统启动后,会执行到SystemServer的startSystemUi()方法,正是在这个方法中启动了SystemUIService。 static final void startSystemUi(Context context, WindowM...

weixin_34341229的博客 186

【JESD79-5之】11 IDD, IDDQ, IPP规格参数和测试条件(IDD, IDDQ, IPP Specification Parameters and Test conditions)

【代码】【JESD79-5之】11 IDD, IDDQ, IPP规格参数和测试条件(IDD, IDDQ, IPP Specification Parameters and Test conditions)

m0_61126667的博客 4855

SystemUI之状态栏StatusBar的加载

一: 在Android 9.0 SystemUI的启动这篇文章中介绍到,我们要启动的服务都是在config_systemUIServiceComponents中配置的。

liangguangyuan的博客 804

别再瞎改注册表了!实测Win10/Win11远程桌面60帧的正确姿势(附ToDesk对比)

本文深入解析Windows远程桌面60帧优化的科学方法,揭示常见误区并提供实测有效的解决方案。从版本差异到硬件加速,再到第三方工具对比(如ToDesk),帮助用户避开无效的注册表修改,实现流畅的远程桌面体验。

weixin_33738555的博客 341

华为OD机试双机位C卷-几何平均值最大子数组(Py/Java/C/C++/Js/Go)

华为OD机试(机考)2026双机位C卷 【几何平均值最大子数组】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【几何平均值最大子数组】。

qq_45776114的博客 1366

Android 12 源码分析 —— 应用层 五(SystemUI的StatusBar类的启动过程和三个窗口的创建)

本文在前文Layout的基础上,进一步介绍各个窗口的创建,并从窗口创建的StatusBar类开始介绍起,是认识StatusBar创建流程的起点

安仔的博客 1万+

基于YOLOv8的城市违建识别系统:从数据集构建到UI界面实现

YOLOv8是Ultralytics公司于2023年推出的最新一代YOLO(You Only Look Once)系列目标检测算法。更高效的骨干网络设计改进的锚框机制更精确的损失函数支持分类、检测、分割等多任务YOLOv8特别适合像违建识别这样的实时检测任务,能够在保持高精度的同时实现快速推理。

YOLO 674

OpenHarmony 源码解析之SystemUi—Statusbar(TS)

SystemUI应用是OpenHarmony中预置的系统应用,为用户提供系统相关信息展示及交互界面,包括系统状态、系统提示、系统提醒等,例如系统时间、电量信息。导入batteryInfo模块,监听系统电池事件,实时获取电池电量状态导入时间模块,调用JS内置函数,实时获取系统时间、日期、星期信息导入Wifi模块,监听设备Wlan通信与连接事件,实时获取Wifi开关、供电、连接名等信息。

2501_91726491的博客 1072

SI好文翻译:铜箔表面纹理对损耗的影响:一个有效的模型(一)

Paul G. Huray发表在DesignCon2010的提出铜箔表面雪球模型的论文。第一部分说明之前的铜箔表面模型只适用于5GHz以内,超过5GHz后就不再准确。

小孟同学的博客 2169

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Android P SystemUI之StatusBar加载流程

相关源码: \frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBar.java \frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBarWindowManager.java...

Sunxiaolin2016的博客 2038

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

phone statusbar.java_SystemUI之StatusBar创建

本文是基于Android 10代码分析。启动 SystemUI服务ActivityManagerService 创建完成时会启动 SystemUI// frameworks/base/services/java/com/android/server/SystemServer.javaprivate void startOtherServices() {mActivityManagerService...

weixin_28951585的博客 361

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Andorid SystemUI, StatusBar, Keyguard

今天在看一个别的问题,突然看到了 SystemUI,StatusBar 这个东西,就顺带看了看,了解一下吧~ SystemUI 概述 自 android2.2 开始 , 原本存在与 framework-res.apk 中的状态栏和下拉通知栏界面控制被分割出一个单独的 apk 文件 , 命名为 SystemUI.apk, 保存在 System/app 文件夹中。在 SystemUI.apk 中

学习记录 2461
上一篇: SystemUI之:Notification前世今生
下一篇: ubuntu 12.10 截图设置
子路雨
博客等级 码龄17年 309粉丝 50原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值