当前位置: 首页 > article >正文

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() {
        @Override
        public 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 界面
    提供一个下拉菜单,显示设备支持的所有刷新率选项。

    <Spinner
        android: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() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Display.Mode mode = modes[position];
            Window window = getWindow();
            window.setPreferredRefreshRate(mode.getRefreshRate());
        }
    
        @Override
        public 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.kler.cn/a/510774.html

相关文章:

  • Flowable 管理各业务流程:流程设计器 (获取流程模型 XML)、流程部署、启动流程、流程审批、流程挂起和激活、任务分配
  • 流量分析复现(第十八届信息安全大赛 第二届长城杯 )
  • Java 对象池管理的高性能工具库 Apache Commons Pool 2
  • 电子电气架构 --- ECU故障诊断指南
  • nss刷题3
  • HBASE学习(一)
  • Spring Boot 集成 MongoDB:启动即注入的便捷实践
  • JAVA-Exploit编写(6)--http-request库文件上传使用
  • 人机交互(包含推荐软件)
  • STM32 中 GPIO 的八种工作模式介绍
  • 第5章:Python TDD定义Dollar对象相等性
  • pnpm安装
  • AUTOSAR从入门到精通-【自动驾驶】高精地图(五)
  • 接口测试自动化实战(超详细的)
  • 若依框架搭建学习
  • Electron实践继续
  • 使用 Helm 安装 Redis 集群
  • 自制游戏——国争
  • JavaScript系列(33)--微前端架构详解
  • C语言之装甲车库车辆动态监控辅助记录系统
  • 第一次在Gitee建仓传码
  • 迈向 “全能管家” 之路:机器人距离终极蜕变还需几步?
  • 多平台下Informatica在医疗数据抽取中的应用
  • SpringCloud -根据服务名获取服务运行实例并进行负载均衡
  • 中型项目中 HTTP 的挑战与解决方案
  • 大型系统中 HTTP 的优化与部署