Android系统开发(十五):从 60Hz 到 120Hz,多刷新率进化简史

引言

欢迎来到“帧率探索实验室”!今天,我们要聊聊 Android 11 中对多种刷新率设备的支持。你可能会问:“这和我写代码有什么关系?”别急,高刷新率不仅仅让屏幕更顺滑,还会直接影响用户体验。想象一下,当你的 app 在 120Hz 上流畅飞舞,而别人的 app 却“卡”在 60Hz,是不是就已经赢了?本文将带你深挖多刷新率支持背后的硬核技术,帮助你的 app 成为用户的心头好。不多说了,先刷个屏,再来深入了解 Hz 的奥秘!
在这里插入图片描述


一、背景

自从手机厂商开始推出高刷新率设备,用户对“流畅体验”的期待不断提升。然而,高刷新率不仅仅是硬件层面的事,系统与应用也需要配合优化。Android 11 正是在这一背景下增加了对多种刷新率的支持。这项技术的核心,是通过 HAL(Hardware Abstraction Layer)、平台代码和全新的 SDK/NDK API,将设备能力和应用需求完美结合。想象一下,从 60Hz 到 90Hz,再到 120Hz,你的 app 瞬间“飞”起来,而用户的惊叹声便是对你努力的最好回报!
在这里插入图片描述


二、原理

多刷新率支持的核心,是如何让设备和应用协同工作,以实现动态调整帧率。

  1. HAL API:定义了设备硬件的能力接口。Android 11 中新增的 android.hardware.graphics.composer@2.4,负责管理设备支持的刷新率范围。
  2. 平台代码:系统解析设备配置文件,读取支持的刷新率选项,并为开发者提供设置接口。
  3. SDK 和 NDK API:通过 Java 或 C++ 调用,开发者可以指定应用的目标帧率。例如,游戏可以设置 120Hz,而视频播放可能限制在 60Hz。

这些组件协作,实现了设备硬件能力与应用实际需求的无缝对接。


三、实现

工具和环境
  • Android Studio 4.0 或更高版本
  • 支持多刷新率的 Android 11 设备
  • 必备工具:ADB 调试工具
步骤详解
  1. 读取设备支持的刷新率

    Display display = getDisplay();
    Display.Mode[] modes = display.getSupportedModes();
    for (Display.Mode mode : modes) {Log.d("RefreshRate", "Mode: " + mode.getRefreshRate() + " Hz");
    }
    
  2. 设置目标帧率
    使用 Surface.setFrameRate() API 设置帧率:

    Surface surface = getSurface();
    surface.setFrameRate(120.0f, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
    
  3. 配置设备支持刷新率
    res/xml/device_config.xml 中定义设备支持的刷新率范围:

    <device><refresh-rate><min>60</min><max>120</max></refresh-rate>
    </device>
    

四、项目实战:高刷新率

在多刷新率支持的开发中,我们将通过三个实际案例展示如何实现动态刷新率设置。每个案例不仅包含详细实现步骤,还会提供代码示例,让你可以直接在项目中运行。


案例 1:高刷新率游戏开发
需求描述

为一款 FPS 游戏设置目标帧率为 120Hz,以提高用户的游戏体验,减少画面延迟感,确保高流畅度。

实现步骤
  1. 检查设备支持的刷新率
    在游戏初始化时,读取设备支持的刷新率范围,确保目标帧率可以被支持。

    Display display = getWindowManager().getDefaultDisplay();
    Display.Mode[] modes = display.getSupportedModes();
    for (Display.Mode mode : modes) {Log.d("GameRefreshRate", "Supported Refresh Rate: " + mode.getRefreshRate() + " Hz");
    }
    
  2. 设置高刷新率
    在游戏的主要渲染窗口(SurfaceViewSurfaceHolder)中,调用 Surface.setFrameRate(),指定目标刷新率为 120Hz。

    Surface surface = surfaceView.getHolder().getSurface();
    surface.setFrameRate(120.0f, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
    
  3. 优化渲染逻辑
    使用 Choreographer 实现高帧率下的精准帧同步。

    Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {renderFrame(); // 渲染游戏帧Choreographer.getInstance().postFrameCallback(this);}
    });
    
最终效果

运行在支持 120Hz 刷新率设备上的游戏画面更流畅,用户操作响应更加快速,显著提升了用户体验。


案例 2:高效视频播放器开发
需求描述

在一个视频播放器中,根据视频帧率动态调整设备的刷新率,以确保流畅播放,并避免额外的功耗。例如,为 30fps 视频设置 60Hz 刷新率,为 60fps 视频设置 120Hz 刷新率。

实现步骤
  1. 获取视频帧率
    在播放器初始化时,解析视频文件,获取其原始帧率。

    MediaExtractor extractor = new MediaExtractor();
    extractor.setDataSource(videoPath);
    MediaFormat format = extractor.getTrackFormat(0);
    int frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
    Log.d("VideoPlayer", "Video Frame Rate: " + frameRate);
    
  2. 动态调整刷新率
    根据帧率,调用 Surface.setFrameRate() 设置设备刷新率。

    float targetRefreshRate = frameRate > 60 ? 120.0f : 60.0f;
    surface.setFrameRate(targetRefreshRate, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
    
  3. 同步播放帧率
    使用 ExoPlayer 的帧回调功能,与设备刷新率同步。

    player.setVideoFrameMetadataListener((presentationTimeUs, releaseTimeNs, format) -> {surface.setFrameRate(format.frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
    });
    
最终效果

视频播放始终匹配设备刷新率,避免因刷新率差异导致的卡顿或撕裂现象,同时节省电量。


案例 3:动态刷新率切换应用
需求描述

开发一个动态切换刷新率的工具应用,用户可以通过界面选择不同的目标刷新率,并实时应用到设备屏幕。

实现步骤
  1. 设计 UI 界面
    提供一个下拉菜单,显示设备支持的所有刷新率选项。

    <Spinnerandroid:id="@+id/spinner_refresh_rate"android:layout_width="wrap_content"android:layout_height="wrap_content"android:entries="@array/refresh_rates" />
    
  2. 获取支持的刷新率
    Activity 初始化时,读取设备支持的刷新率,并填充到下拉菜单中。

    Display display = getWindowManager().getDefaultDisplay();
    Display.Mode[] modes = display.getSupportedModes();
    ArrayList<String> refreshRates = new ArrayList<>();
    for (Display.Mode mode : modes) {refreshRates.add(mode.getRefreshRate() + " Hz");
    }
    ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, refreshRates);
    spinner.setAdapter(adapter);
    
  3. 实现动态切换逻辑
    根据用户选择,动态应用刷新率。

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {Display.Mode mode = modes[position];Window window = getWindow();window.setPreferredRefreshRate(mode.getRefreshRate());}@Overridepublic void onNothingSelected(AdapterView<?> parent) {}
    });
    
  4. 适配不同设备
    检查设备是否支持动态刷新率切换,确保应用在低版本设备上可以正常运行。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {// 支持 Android 11 以上的设备动态刷新率切换
    } else {Log.w("RefreshRateApp", "Dynamic refresh rate not supported on this device.");
    }
    
最终效果

用户可以通过界面实时切换刷新率,应用直接调整屏幕刷新率,感受到流畅与动态切换的便利。


归纳

这些项目展示了多刷新率支持的不同应用场景,包括高帧率游戏、流畅视频播放器和动态刷新率工具。每个案例都提供了详细的代码与实现步骤,可以直接用于实践或改进开发效率。

五、避坑

  1. 设备支持问题:并非所有设备都支持高刷新率,需检查兼容性。
  2. 耗电问题:高刷新率耗电量增加,需平衡性能与功耗。
  3. API 调用失败:确保使用了 Android 11 或更高版本的 API。

六、快稳省

优点
  • 极大提升用户体验。
  • 提供灵活的帧率设置接口,满足不同场景需求。
缺点
  • 增加开发复杂度。
  • 不支持低版本设备。

七、性能

使用 GPU Profiler 监测高刷新率下的应用性能,评估帧率与资源消耗的平衡点。


八、未来

未来,Android 系统或将支持更智能的动态帧率调整,结合 AI 技术预测用户操作,进一步优化资源分配。

本文从技术背景、实现原理到项目实战,为你详细解析了 Android 11 多刷新率支持。希望通过这些技术,让你的应用体验更上一层楼!


九、开发者选项

设置菜单中新增了一个开发者选项,它可以使用当前刷新率在屏幕上切换叠加层。新选项位于设置 > 系统 > 开发者选项 > 显示刷新频率下。
在这里插入图片描述

十、参考资料

以下是撰写本文时参考的技术资源,涵盖书籍、论文、官方网站和博客,帮助读者进一步深入理解多刷新率支持的实现与优化。


官方文档
  1. Android Developers Documentation

    • 官方多刷新率支持文档
      Android 官方提供的多刷新率支持指南,详细介绍了功能组成、API 使用方法和平台支持。
  2. Surface API Reference

    • Surface.setFrameRate
      提供 Surface 类的完整 API 说明,包含帧率设置和兼容性选项。
  3. NDK Documentation

    • NDK API for Refresh Rate
      介绍了通过 NDK 实现刷新率动态调整的相关工具和方法。

书籍
  1. 《Android 高级编程》
    作者:[Joseph Annuzzi Jr., Lauren Darcey, Shane Conder]
    讲解 Android 开发高级特性,包括硬件抽象层和系统架构,适合了解多刷新率支持的底层实现。

  2. 《Android 深入理解与实战》
    作者:邓凡平
    提供 Android 系统机制与应用开发的深入剖析,是学习 Android 系统级开发的好工具书。

  3. 《Graphics Programming Black Book》
    作者:Michael Abrash
    虽然主要针对图形编程基础,但对优化刷新率和性能调优有很大的启发。


论文
  1. “Variable Refresh Rate Displays and Their Impact on Visual Performance”
    描述多刷新率技术在视觉效果和用户体验中的重要性,涵盖了刷新率动态调整的研究数据。

  2. “Adaptive Refresh Rate Mechanisms in Modern Display Technologies”
    探讨了现代显示技术中自适应刷新率机制的设计与实现。


技术博客
  1. Android Developers Blog: New Features in Android 11
    Android 官方博客详细介绍了 Android 11 的新特性,包括多刷新率支持。

  2. Medium: Implementing High Refresh Rates in Android Apps
    技术博主在实际项目中如何实现动态刷新率设置的案例分享。

  3. CSDN: 动态刷新率实现的坑与优化
    提供在实际开发过程中遇到的问题及解决方案。


社区资源
  1. Stack Overflow

    • Handling Variable Refresh Rates
      解答开发者在多刷新率开发中常见的问题,拥有丰富的社区实践经验。
  2. GitHub

    • 示例代码仓库:Dynamic Refresh Rate Demo
      提供完整的多刷新率实现样例代码,可直接下载学习。

工具与环境
  1. Android Studio Arctic Fox 或更高版本
    支持 Android 11 开发的 IDE。

  2. 设备

    • 测试设备需支持多刷新率,如 Pixel 5、Samsung Galaxy S 系列等。
  3. 工具

    • adb shell:用于调试和检查设备支持的刷新率。
    • Choreographer:实现帧同步的重要工具。

这些参考资料涵盖了理论知识、实践经验和代码示例,帮助开发者全面掌握多刷新率技术的实现与优化。如果你有更多推荐或想法,欢迎在评论区留言交流! 😊

文章结尾

欢迎关注我们的 GongZhongHao:码农的乌托邦,程序员的精神家园!获取更多技术干货,我们一起提升代码水平!

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

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

相关文章

基于JAVA的微信点餐小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

ChatGPT结合Excel辅助学术数据分析详细步骤分享!

目录 一.Excel在学术论文中的作用✔ 二.Excel的提示词✔ 三. 编写 Excel 命令 四. 编写宏 五. 执行复杂的任务 六. 将 ChatGPT 变成有用的 Excel 助手 一.Excel在学术论文中的作用✔ Excel作为一种广泛使用的电子表格软件&#xff0c;在学术论文中可以发挥多种重要作用&a…

国内有哪些著名的CRM系统提供商?

嘿&#xff0c;你有没有想过&#xff0c;在这个信息爆炸的时代里&#xff0c;企业怎么才能更好地管理客户关系呢&#xff1f;答案就是使用高效的CRM系统。今天我就来给大家聊聊那些在国际上非常有名的CRM系统提供商吧。 悟空CRM 首先不得不提的就是悟空CRM了&#xff01;这可…

Linux中的几个基本指令(二)

文章目录 1、cp指令例一&#xff1a;例二&#xff1a;例三&#xff1a;例四&#xff1a;例五&#xff1a; 2、mv 指令例一&#xff1a;例二&#xff1a; 3、cat指令例一&#xff1a; 4、tac指令5、which指令6、date指令时间戳&#xff1a;7、zip指令 今天我们继续学习Linux下的…

mock可视化生成前端代码

介绍&#xff1a;mock是我们前后端分离的必要一环、ts、axios编写起来也很麻烦。我们就可以使用以下插件&#xff0c;来解决我们的问题。目前支持vite和webpack。&#xff08;配置超级简单&#xff01;&#xff09; 欢迎小伙伴们提issues、我们共建。提升我们的开发体验。 vi…

9. 神经网络(一.神经元模型)

首先&#xff0c;先看一个简化的生物神经元结构&#xff1a; 生物神经元有多种类型&#xff0c;内部也有复杂的结构&#xff0c;但是可以把单个神经元简化为3部分组成&#xff1a; 树突&#xff1a;一个神经元往往有多个树突&#xff0c;用于接收传入的信息。轴突&#xff1a;…

Web 音视频(二)在浏览器中解析视频

前言 浏览器中已经能直接播放视频&#xff0c;为什么还需要手动写代码解析&#xff1f; 因为&#xff0c;某些场景需要对视频进行更细致的处理&#xff0c;比如截取关键帧、提取视频中的文字、人物打码、极低延时播放视频等等。 总之&#xff0c;除了最单纯的视频播放外&…

ETLCloud在iPaas中的是关键角色?

在当今的数字化时代&#xff0c;企业越来越依赖于其处理和分析数据的能力。为了实现这一目标&#xff0c;企业需要将各种异构的应用和数据源集成在一起&#xff0c;形成一个统一的数据视图。在这一过程中&#xff0c;ETL&#xff08;Extract, Transform, Load&#xff09;和iPa…

以太网实战AD采集上传上位机——FPGA学习笔记27

一、设计目标 使用FPGA实现AD模块驱动采集模拟电压&#xff0c;通过以太网上传到电脑上位机。 二、框架设计 数据位宽转换模块&#xff08;ad_10bit_to_16bit&#xff09;&#xff1a;为了方便数据传输&#xff0c;数据位宽转换模块实现了将十位的 AD 数据转换成十六位&#…

YOLOv1、YOLOv2、YOLOv3目标检测算法原理与实战第十三天|YOLOv3实战、安装Typora

1.学习哔哩哔哩《YOLOv1、YOLOv2、YOLOv3目标检测算法原理与实战》 炮哥带你学视频链接 第5章 YOLOv3实战 5.1 YOLOv3实战先导 5.2 pycharm与anaconda的安装 之前已经安装过了&#xff0c;见Pytorch框架与经典卷积神经网络与实战第一天|安装PyCharm&Anaconda&#xff0…

数据库SQLite和SCADA DIAView应用教程

课程简介 此系列课程大纲主要包含七个课时。主要使用到的开发工具有&#xff1a;SQLite studio 和 SCADA DIAView。详细的可成内容大概如下&#xff1a; 1、SQLite 可视化管理工具SQLite Studio &#xff1a;打开数据库和查询数据&#xff1b;查看视频 2、创建6个变量&#x…

YOLOv8改进,YOLOv8检测头融合DSConv(动态蛇形卷积),并添加小目标检测层(四头检测),适合目标检测、分割等

精确分割拓扑管状结构例如血管和道路,对各个领域至关重要,可确保下游任务的准确性和效率。然而,许多因素使任务变得复杂,包括细小脆弱的局部结构和复杂多变的全局形态。在这项工作中,注意到管状结构的特殊特征,并利用这一知识来引导 DSCNet 在三个阶段同时增强感知:特征…

Addressable学习

AssetsBundle是Unity的资源管理机制,将资源打包到AssetsBundle资源包并提供接口能从ab包里面加载资源出来。有了这个机制以后&#xff0c;我们要做资源管理&#xff0c;还需要做: a: 根据项目需求,编写编辑器扩展,提供指定资源打入对应bundle包工具策略; b: 根据项目的需求,资源…

概率密度函数(PDF)分布函数(CDF)——直方图累积直方图——直方图规定化的数学基础

对于连续型随机变量&#xff0c;分布函数&#xff08;Cumulative Distribution Function, CDF&#xff09;是概率密度函数&#xff08;Probability Density Function, PDF&#xff09;的变上限积分&#xff0c;概率密度函数是分布函数的导函数。 如果我们有一个连续型随机变量…

深入解析:Docker 容器如何实现文件系统与资源的多维隔离?

目录 一、RootFs1. Docker 镜像与文件系统层2. RootFs 与容器隔离的意义 二、Linux Namespace1. 进程命名空间1.1 lsns 命令说明1.2 查看“祖先进程”命名空间1.3 查看当前用户进程命名空间 2. 容器进程命名空间2.1 查看容器进程命名空间列表2.2 容器进程命名空间的具体体现 三…

深度学习|表示学习|卷积神经网络|由参数共享引出的特征图|08

如是我闻&#xff1a; Feature Map&#xff08;特征图&#xff09;的概念与 Parameter Sharing&#xff08;参数共享&#xff09;密切相关。换句话说&#xff0c;参数共享是生成 Feature Map 的基础。Feature Map 是卷积操作的核心产物&#xff0c;而卷积操作的高效性正是由参数…

【Linux网络编程】传输层协议

目录 一&#xff0c;传输层的介绍 二&#xff0c;UDP协议 2-1&#xff0c;UDP的特点 2-2&#xff0c;UDP协议端格式 三&#xff0c;TCP协议 3-1&#xff0c;TCP报文格式 3-2&#xff0c;TCP三次握手 3-3&#xff0c;TCP四次挥手 3-4&#xff0c;滑动窗口 3-5&#xf…

ARP 表、MAC 表、路由表、跨网段 ARP

文章目录 一、ARP 表1、PC2、路由器 - AR22203、交换机 - S57004、什么样的设备会有 ARP 表&#xff1f; 二、MAC 表什么样的设备会有 MAC 表&#xff1f; 三、路由表什么样的设备会有路由表&#xff1f; 四、抓取跨网段 ARP 包 所谓 “透明” 就是指不用做任何配置 一、ARP 表…

算法10(力扣20)-有效的括号

1、问题 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类…

每日一题——二叉树的前序遍历和中序遍历和后序遍历

文章目录 二叉树的前序、中序与后序遍历题目描述数据范围&#xff1a;示例&#xff1a;示例 1&#xff1a; 解题思路1. 递归法2. 迭代法 代码实现&#xff08;递归法&#xff09;代码解析示例输出复杂度分析 中序遍历后序遍历 二叉树的前序、中序与后序遍历 题目描述 给定一棵…