安卓车载多屏互动副屏底部有黑线条NavigationBar分析

news2024/9/20 11:01:02

背景:

在学习了马哥的wms和多屏互动课程后,大家普遍都可以跟着做出如下图效果的多屏互动:

在这里插入图片描述

其实初略来看这个成果已经完成一个多屏互动项目大部分功能,但是其实还是有一些bug的存在,今天我们就来分析一下多屏互动相关的bug补充哈。

副屏Activity底部有黑线条分析

虚拟屏幕下下面的所有Activity在底部都会显示一个黑线条,具体如图展示:
在这里插入图片描述

明显第二屏幕的底部黑线看起来很诡异,下面这个黑线条其实是我们不需要的,这里就需要分析一下为啥会有这个黑线条

分析思路:

dumpsys SurfaceFlinger分析
在最后合成部分查看副屏display的图层
在这里插入图片描述
明显看到了Activity上面还有一个NavigationBar2这个图层,那么接下来其实就好办了,找到这个NavigationBar2窗口添加地方

看看NavigationBar2这个图层对应窗口是谁创建的

Window #0 Window{5819104 u0 NavigationBar2}:
    mDisplayId=2 rootTaskId=1140 mSession=Session{4e45c83 740:u0a10109} mClient=android.os.BinderProxy@e1cd996
    mOwnerUid=10109 showForAllUsers=true package=com.android.systemui appop=NONE
    mAttrs={(0,0)(fillx168) gr=BOTTOM CENTER_VERTICAL sim={adjust=pan} layoutInDisplayCutoutMode=always ty=NAVIGATION_BAR fmt=TRANSLUCENT
      fl=NOT_FOCUSABLE NOT_TOUCH_MODAL WATCH_OUTSIDE_TOUCH SPLIT_TOUCH FLAG_SLIPPERY
      pfl=LAYOUT_SIZE_EXTENDED_BY_CUTOUT COLOR_SPACE_AGNOSTIC USE_BLAST FIT_INSETS_CONTROLLED TRUSTED_OVERLAY
      bhv=DEFAULT

明显看到是package=com.android.systemui创建,那么接下来怎么找对应的NavigationBar2的窗口创建呢?
这里马哥老粉丝学员肯定会想到是不是可以打堆栈呢?
这里确实是可以的,因为一般NavigationBar2属于窗口最后肯定是需要执行下面这一部分WindowManager.addView的代码
在这里插入图片描述
具体堆栈就不贴了,属于学员们自己要学会的基本功。
最后其实是新屏幕创建准备好了以后会通知systemui下面代码
在这里插入图片描述
这里再看看createNavigationBar
在这里插入图片描述
这里核心关键可以看到有一个拦截是否要创建NavigationBar,来看看shouldCreateNavBarAndTaskBar方法

 private boolean shouldCreateNavBarAndTaskBar(Context context, int displayId) {
        final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
				//主屏幕调用是setting值
        if (displayId == mDisplayTracker.getDefaultDisplayId() &&
                LineageSettings.System.getIntForUser(context.getContentResolver(),
                        LineageSettings.System.FORCE_SHOW_NAVBAR, 0,
                        UserHandle.USER_CURRENT) == 1) {
            return true;
        }
        //非主屏幕就调用wms的hasNavigationBar接口
        try {
            return wms.hasNavigationBar(displayId);
        } catch (RemoteException e) {
            // Cannot get wms, just return false with warning message.
            Log.w(TAG, "Cannot get WindowManager.");
            return false;
        }
    }

下面来看看wms的hasNavigationBar接口:

    public boolean hasNavigationBar(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            if (dc == null) {
                return false;
            }
            return dc.getDisplayPolicy().hasNavigationBar();
        }
    }

这里看看hasNavigationBar方法
在这里插入图片描述
就是靠两个标志位来的主要我们来看看mHasNavigationBar,mForceNavbar看了是不满足的
在这里插入图片描述
对于副屏主要就是靠mDisplayContent.supportsSystemDecorations()来决定:
在这里插入图片描述
可以看到这里的条件还是比较严格的,这里大部分和我们的display创建参数有关系
1、受信任display
2、有设置FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
(当然也还有其他settings也可以控制,大家可以一一确定,默认一般setting为false)
那么我们dumpsys display确认一下
在这里插入图片描述
确实看到创建副屏满足上面条件,到此整个副屏显示一条黑线就清楚,本质就是显示了一个NavigationBar盖在上面,为啥显示NavigationBar是因为副屏创建时候有相关的FLAG让显示及是相关的Trust屏幕

如何修改

原因知道了,那么修改就简单多了,可以直接修改FLAG也好,或者直接暴力修改让所有副屏都不显示NavigationBar也可以,这里其实建议大家可以自己根据副屏的其他特性判断,自己根据情况细分,这里只是为了演示就直接修改成不显示:
在这里插入图片描述
修改后看看效果:
在这里插入图片描述
明显可以看到副屏已经没有了那个小黑条,即不在副屏创建NavigationBar。

具体详情试看方式:
投屏专题部分:
https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg

更多framework详细代码和资料参考如下链接

hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

更多framework假威风耗:androidframework007

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1973041.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA实现SDI视频接收转USB3.0传输,GS2971+FT601方案,提供4套工程源码和QT上位机源码

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本博已有的FPGA驱动USB通信方案FPGA基于GS2971的SDI视频解码方案FPGA基于FT601的USB3.0视频传输方案 3、详细设计方案设计原理框图SDI 相机GS2971-SDI解码芯片解读BT1120转RGB888图像缓存FT601-USB3.0芯…

计算机毕业设计选题推荐-校内跑腿业务系统-Java/Python项目实战

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

深入理解操作系统--绪论

文章目录 概述操作系统的基本概念多用户系统用户和组进程 小结 概述 最近在读操作系统,发现一些新的概念。写出来,让自己印象更深,希望也帮助一些不懂的朋友;但愿有所帮助吧。 操作系统的基本概念 计算机都包含操作系统的基本程…

自动化测试的回归策略!

在快速迭代的软件开发过程中,确保软件质量的稳定性和可靠性是每一个开发团队都面临的重要挑战。其中,回归测试作为验证软件变更后是否仍然满足原有需求的重要手段,其重要性不言而喻。而自动化测试的回归策略,正是为了应对这一挑战…

学习记录——day25 多线程编程 临界资源 临界区 竞态 线程的同步互斥机制(用于解决竟态)

目录 ​编辑 一、多进程与多线程对比 二、 临界资源 临界区 竞态 例1:临界资源 实现 输入输出 例2:对临界资源 进行 减减 例子3:临界资源抢占使用 三、线程的同步互斥机制(用于解决竟态) 3.1基本概念 3.2线…

C#实现数据采集系统-系统优化服务封装

系统优化-服务封装 现在我们调用modbustcp和mqtt都直接在Program,所有加载和功能都混合在一起,比较难以维护 类似asp.net core项目的Program.cs代码如下,构建服务配置和启动 要实现的效果,Main方法中就是一个服务启动,只需要几行代码 分析代码 这里分成两部分,一…

医疗健康类应用,适合采用哪些风格?本文归纳之,并附案例。

医疗健康类应用的设计风格应该注重用户友好性、专业性和清晰易懂。以下是一些适合医疗健康类应用采用的设计风格: 1. 清晰简洁的界面: 医疗健康类应用的界面设计应该简洁清晰,避免过多花哨的元素,让用户能够快速找到他们需要的信…

JAVA-案列练习-ATM项目

在JAVA入门学习后进行的项目练习——模拟ATM系统。 目录 1.设计内容和要求 2.代码实现 (1)ATM账号类的定义 (2)ATM类中的操作 (3)操作说明 3.总结 1.设计内容和要求 01 系统架构搭建,欢…

Spring Cloud全解析:注册中心之Eureka架构介绍

Eureka架构介绍 Eureka在设计时采用的是AP原则,是Netflix的一个子模块,用于微服务的服务注册与发现 P:Partition tolerance,网络分区容错。类似多机房部署,保证服务稳定性A: Availability,可用性C:Consistency ,一致…

【时时三省】(C语言基础)函数递归

山不在高,有仙则名。水不在深,有龙则灵。 ——csdn时时三省 什么是递归 程序调用自身的编程技巧称为递归。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂…

Jenkin:动态选择Git分支

Jenkin:动态选择Git分支 build时输入分支 构建的时候添加一个字符参数 选择设置的变量,需要用${}括起来 构建时的效果 build时下拉选择分支 安装Git 参数插件 添加git参数 选择设置的变量,需要用${}括起来 构建时的效果

如何在不同设备上检查您的 IP 地址?

IP 地址(Internet 协议地址)是网络上设备的唯一标识符。了解如何查找 IP 地址对于解决网络问题、设置网络设备和维护网络安全非常重要。本文将详细介绍如何在不同设备上检查 IP 地址,包括 Windows 计算机、Mac 计算机、智能手机(A…

计算机网络快速入门---百年前人们不敢想象的黑科技

目录 1.引言 2.快递VS网络 3.网络模型 3.1两个模型 3.2传输过程 4.IP 4.1IP简介 4.2解决方案一 5.局域网和互联网 5.1局域网说明 5.2互联网说明 6.网络攻击 1.引言 注意,这个只是一个快速入门,不是我开始进行系统学习了,这个博客…

【unity小技巧】unity性能优化以及如何进行性能测试

文章目录 前言GPU性能优化打包素材 CPU性能优化代码执行优化 性能测试Vector2.Distance 和 sqrMagnitude哪个好?动画切换优化shader属性优化 URP渲染器资产优化对象池优化删除没必要的空函数图片、音乐音效、贴图等素材压缩ScriptableObject优化参数参考完结 前言 …

数据结构与算法-15高级数据结构_树论(堆树)

堆树 1 简介 1.1 什么是堆树 定义:堆树是一种特殊的完全二叉树,其中每个节点的值都遵循一定的堆属性。具体来说,堆分为最大堆和最小堆。 最大堆:在最大堆中,每个父节点的值都大于或等于其任何子节点的值。这意味着…

SpringMVC02

1.拦截器 1.1基本概念 SpringMVC 中的Interceptor拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆等操作。对于SpringMVC拦截器的定义方式 有两种: 实现接口:org.springframework.web.ser…

CAD-文字、图块、多行文字,沿多段线对齐到多段线的顶点,沿直线进行均分,都可以操作

图块和文字对齐直线-均布直线-对齐多段线顶点-旋转平行 (defun c:duiqi () ;将图块与直线对齐,并均分。;先创建的图块排最右;先等分的坐标排最右;刚好对应了(defun MoveToPosition (Blockname p_list / ent refPoint dx dy) ;移动对象到指定坐标(prompt "\nSel…

【Git-驯化】一文学会git中对代码进行存储操作:git stash技巧

【Git-驯化】一文学会git中对代码进行存储操作:git stash技巧 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 免费获取相关内…

@change事件传参

change事件传参 change"(value)>handleChange(value, item,index)" 这样可以接收index参数区分是哪一个组件事件&#xff0c;又可以接收子组件传的value值 <div class"boxItem" v-for"(item, index) in checkPeopleList" :key"inde…

VUE实现TAB切换不同页面

VUE实现TAB切换不同页面 实现效果 资源准备 ReceiveOrderList, TodoListMulti, SignList 这三个页面就是需要切换的页面 首页代码 <template><div><el-tabs v-model"activeTab" type"card" tab-click"handleTabClick"><…