Android智能座舱,视频播放场景,通过多指滑屏退回桌面,闪屏问题的另一种解法

一、背景
Android智能座舱,视频播放场景,通过多指滑屏退回桌面,会出现闪屏问题。

二、问题定位以及修改方案
通过录屏,然后一帧一帧播放的方式,发现闪屏是因为,多指的情况下,不仅触发了退回桌面的动作,还触发了调节视频app的亮度,以及视频的快进和快退的动作,几种UI刷新叠加起来,造成了闪屏的现象。

除了调整手势识别的方法解决闪屏的问题,还有一种方式,就是退出页面的时候截屏,卡住UI的刷新,也能解决闪屏的问题。

1. 步骤一
通过如下函数takeScreenshot,截取主屏的bitmap,但是通过SurfaceControl.captureDisplay获取到的bitmap对应的buffer是SurfaceControl.ScreenshotHardwareBuffer,属于hadware bitmaps,无法通过software rendering,会报如下错误:
Software rendering doesn’t support hardware bitmaps

必须通过如下方式,将hardware bitmap转成soft bitmap:
Bitmap softwareBitmap = screenShot.copy(Bitmap.Config.ARGB_8888, true);

    private Bitmap takeScreenshot(int displayId) {if (displayId != 0) {return null;}// Take the screenshotfinal IBinder displayToken = SurfaceControl.getInternalDisplayToken();final SurfaceControl.DisplayCaptureArgs captureArgs =new SurfaceControl.DisplayCaptureArgs.Builder(displayToken).build();final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =SurfaceControl.captureDisplay(captureArgs);Bitmap screenShot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();if (screenShot == null) {Log.e(TAG, "Failed to take fullscreen screenshot");return null;}// OptimizationscreenShot.setHasAlpha(false);Bitmap softwareBitmap = screenShot.copy(Bitmap.Config.ARGB_8888, true);if (screenShot != null) {screenShot.recycle();screenShot = null;}return softwareBitmap;}

2.步骤二
通过函数createScreenshotLayer,将takeScreenshot 获取到的software bitmap,生成对应的SurfaceControl ,也就是底层的Layer数据。

    private SurfaceControl createScreenshotLayer(Bitmap bitmap) {Log.w(TAG, "launchHomeFromFivePointerCatch: createScreenshotLayer bitmap : " + bitmap + ", w = " + bitmap.getWidth()+ " ,h = " + bitmap.getHeight());// 创建 SurfaceControl 图层SurfaceControl surfaceControl = new SurfaceControl.Builder().setName("ScreenshotLayer").setBufferSize(bitmap.getWidth(), bitmap.getHeight()).setFormat(PixelFormat.TRANSLUCENT).build();Surface surface = new Surface(surfaceControl);Canvas canvas = surface.lockCanvas(null);canvas.drawBitmap(bitmap, 0, 0, null);surface.unlockCanvasAndPost(canvas);return surfaceControl;}

3. 步骤三
通过playExitAnimation实现冻屏或者刷帧的动作,最后测试发现,冻屏比较适合,也相对简单。刷帧的方式,因为不能很好的掌握UI的调整和显示的时间,无法正确确定刷帧的起始和结束的时机。

    private void playExitAnimation(SurfaceControl surfaceControl) {Log.w(TAG, "launchHomeFromFivePointerCatch: playExitAnimation surfaceControl : " + surfaceControl);SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();方案1:冻屏/*// 设置动画属性/transaction.setMatrix(surfaceControl, 0.5f, 0, 0, 0.5f); // 缩放到 50%/transaction.setAlpha(surfaceControl, 0.0f); // 设置透明度为 0transaction.setLayer(surfaceControl, Integer.MAX_VALUE);transaction.show(surfaceControl);transaction.apply();// 延时销毁图层mHandler.postDelayed(() -> {transaction.remove(surfaceControl).apply();}, 500); // 动画持续 500ms*/float startScale = 1.0f;float endScale = 0.5f;float startAlpha = 1.0f;float endAlpha = 0.0f;int duration = 500;long startTime = System.currentTimeMillis();方案2:通过handler 刷帧/*mHandler.post(new Runnable() {@Overridepublic void run() {if (!surfaceControl.isValid()) {return;}long elapsedTime = System.currentTimeMillis() - startTime;if (elapsedTime > duration) return;float progress = (float) elapsedTime / duration;float currentScale = startScale + progress * (endScale - startScale);float currentAlpha = startAlpha + progress * (endAlpha - startAlpha);Log.w(TAG, "launchHomeFromFivePointerCatch: playExitAnimation progress : -----------" + progress+ ", currentScale = " + currentScale + ", currentAlpha = " + currentAlpha);//SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();transaction.setMatrix(surfaceControl, currentScale, 0, 0, currentScale); // 设置缩放transaction.setAlpha(surfaceControl, currentAlpha); // 设置透明度transaction.setLayer(surfaceControl, Integer.MAX_VALUE);transaction.show(surfaceControl);transaction.apply();mHandler.post(this);}});*/方案3:通过Choreographer刷帧Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {long startTime = System.nanoTime();@Overridepublic void doFrame(long frameTimeNanos) {if (!surfaceControl.isValid()) {return;}float progress = (frameTimeNanos - startTime) / (float) (duration * 1_000_000); // 计算进度if (progress > 1.0f) return;float currentScale = startScale + progress * (endScale - startScale);float currentAlpha = startAlpha + progress * (endAlpha - startAlpha);Log.w(TAG, "launchHomeFromFivePointerCatch: playExitAnimation progress : -----------" + progress+ ", currentScale = " + currentScale + ", currentAlpha = " + currentAlpha);//transaction.setMatrix(surfaceControl, currentScale, 0, 0, currentScale); // 设置缩放transaction.setAlpha(surfaceControl, currentAlpha); // 设置透明度transaction.setLayer(surfaceControl, Integer.MAX_VALUE);transaction.show(surfaceControl);transaction.apply();Choreographer.getInstance().postFrameCallback(this); // 下一帧}});mHandler.postDelayed(() -> {//SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();transaction.hide(surfaceControl); // 隐藏图层transaction.remove(surfaceControl); // 移除图层transaction.apply();surfaceControl.release(); // 释放资源}, duration);}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Keil+VSCode优化开发体验

目录 一、引言 二、详细步骤 1、编译器准备 2、安装相应插件 2.1 安装C/C插件 2.2 安装Keil相关插件 3、添加keil环境变量 4、加载keil工程文件 5、VSCode中成功添加工程文件后可能出现的问题 5.1 编码不一致问题 6、在VSCode中进行编译工程以及烧录程序 7、效果展示…

Llama模型文件介绍

文章目录 概要文件组成 概要 在使用 LLaMA(Large Language Model Meta AI)权重时,通常会涉及到与模型权重存储和加载相关的文件。这些文件通常是以二进制格式存储的,具有特定的结构来支持高效的模型操作。以下以Llama-7B为例&…

Spring Web入门练习

加法计算器 约定前后端交互接⼝ 约定 "前后端交互接⼝" 是进⾏ Web 开发中的关键环节. 接⼝⼜叫 API(Application Programming Interface), 我们⼀般讲到接⼝或者 API,指的都是同⼀个东西. 是指应⽤程序对外提供的服务的描述, ⽤于交换信息…

Easyexcel(5-自定义列宽)

相关文章链接 Easyexcel(1-注解使用)Easyexcel(2-文件读取)Easyexcel(3-文件导出)Easyexcel(4-模板文件)Easyexcel(5-自定义列宽) 注解 ColumnWidth Data…

FIFO和LRU算法实现操作系统中主存管理

FIFO&#xff0c;用数组实现 1和2都是使用nextReplace实现新页面位置的更新 1、不精确时间&#xff1a;用ctime输出运行时间都是0.00秒 #include <iostream> #include <iomanip> #include<ctime>//用于计算时间 using namespace std;// 页访问顺序 int pa…

Unity3d场景童话梦幻卡通Q版城镇建筑植物山石3D模型游戏美术素材

注明&#xff1a;网络素材&#xff0c;仅供学习使用&#xff01; https://download.csdn.net/download/elineSea/90017291

batchnorm与layernorn的区别

1 原理 简单总结&#xff1a; batchnorn 和layernorm是在不同维度上对特征进行归一化处理。 batchnorm在batch这一维度上&#xff0c; 对一个batch内部所有样本&#xff0c; 在同一个特征通道上进行归一化。 举个例子&#xff0c; 假设输入的特征图尺寸为16x224x224x256&…

SpringAOP模拟实现

文章目录 1_底层切点、通知、切面2_切点匹配3_从 Aspect 到 Advisor1_代理创建器2_代理创建时机3_Before 对应的低级通知 4_静态通知调用1_通知调用过程2_模拟 MethodInvocation 5_动态通知调用 1_底层切点、通知、切面 注意点&#xff1a; 底层的切点实现底层的通知实现底层的…

标准驱动开发(Linux2.6(cdev) 的开发)

Linux2.6&#xff08;cdev&#xff09; 的开发 目录 Linux2.6&#xff08;cdev&#xff09; 的开发 回顾 Linux2.6&#xff08;cdev&#xff09; 的开发 了解一下 Linux2.6 开发框架 学习 Linux2.6 的相关接口 1、申请设备号&#xff08;alloc_chrdev_region&#xff09…

硬件知识 cadence16.6 原理图输出为pdf 网络名下划线偏移 (ORCAD)

1. cadence原理图输出为PDF网络名下划线偏移 生这种情况的原因 1. 设计的原理图图纸大小比正常的 A4图纸大。 2. 打印为PDF 的时候&#xff0c;打印机的设置有问题。 2.cadence原理图输出为 PDF网络名下划线偏移的情况 可以看到上图&#xff0c;网络名往上漂移。 3. 解决办法 …

HarmonyOs DevEco Studio小技巧31--卡片的生命周期与卡片的开发

Form Kit简介 Form Kit&#xff08;卡片开发服务&#xff09;提供一种界面展示形式&#xff0c;可以将应用的重要信息或操作前置到服务卡片&#xff08;以下简称“卡片”&#xff09;&#xff0c;以达到服务直达、减少跳转层级的体验效果。卡片常用于嵌入到其他应用&#xff0…

SSRF漏洞利用

2.漏洞利用 2.1 SSRF中URL的伪协议 file:// 从⽂件系统中获取⽂件内容&#xff0c;如&#xff0c;file:///etc/passwd dict:// 字典服务器协议&#xff0c;访问字典资源&#xff0c;如dict://ip:6379/info sftp:// ssh⽂件传输协议或安全⽂件传输协议 ldap:// 轻量级⽬录访问…

nacos镜像启动时候报Public Key Retrieval is not allowed

在nacos的配置文件里加上一句allowPublicKeyRetrievaltrue

【pytorch-04】:线性回归案例(手动构建)

文章目录 1 构建数据集2 构建假设函数3 损失函数4 优化方法5 训练函数6.总结 1 构建数据集 为什么构建数据加载器&#xff1f; 在进行训练的时候都是采用的不是全部的数据&#xff0c;而是采用一个batch_size的数据进行训练&#xff0c;每次向模型当中送入batch_size数据&#…

实验室管理效率提升:Spring Boot技术的力量

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

STM32H7开发笔记(2)——H7外设之多路定时器中断

STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断 文章目录 STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断0.引言1.CubeMX配置2.软件编写 0.引言 本文PC端采用Win11STM32CubeMX4.1.0.0Keil5.24.2的配置&#xff0c;硬件使用STM32H…

springboot基于微信小程序的旧衣回收系统的设计与实现

摘 要 微信小程序的旧衣回收系统是一种专为环保生活设计的应用软件。这款小程序的主要功能包括&#xff1a;系统首页、个人中心、用户管理、回收人员管理、旧衣服分类管理、旧衣信息管理、回收预约管理、回收派单管理、回收订单管理、积分商品管理、积分兑换管理、管理员管理、…

路由缓存后跳转到新路由时,上一路由中的tip信息框不销毁问题解决

上一路由tip信息框不销毁问题解决 路由缓存篇问题描述及截图解决思路关键代码 路由缓存篇 传送门 问题描述及截图 路由缓存后跳转新路由时&#xff0c;上一个路由的tip信息框没销毁。 解决思路 在全局路由守卫中获取DOM元素&#xff0c;通过css去控制 关键代码 修改文…

40分钟学 Go 语言高并发:并发下载器开发实战教程

并发下载器开发实战教程 一、系统设计概述 1.1 功能需求表 功能模块描述技术要点分片下载将大文件分成多个小块并发下载goroutine池、分片算法断点续传支持下载中断后继续下载文件指针定位、临时文件管理进度显示实时显示下载进度和速度进度计算、速度统计错误处理处理下载过…

【前端】JavaScript中的indexOf()方法详解:基础概念与背后的应用思路

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是indexOf()方法&#xff1f;参数解释返回值示例 &#x1f4af;indexOf() 方法的工作原理&#x1f4af;特殊案例&#xff1a;undefined 的处理示例代码图示解释 &#x1f4af;i…