如何使用Kotlin正确获取Android系统帧率
原有代码问题说明
你写的代码无法生效,是几个基础错误导致的:
- 类型声明错误:
SystemClock.elapsedRealtime()返回值是Long类型的毫秒时间戳,不是SystemClock类的实例,代码本身就存在类型不匹配的编译问题 - 统计逻辑完全不成立:连续两次同步调用
elapsedRealtime()的时间差几乎为0,既没有绑定系统帧渲染事件,也没有跨帧统计时间间隔,计算出的数值没有任何实际意义,甚至会触发除零崩溃
Kotlin实现帧率获取方案
Android系统提供了Choreographer类对接Vsync垂直同步信号,每帧渲染完成都会触发对应回调,基于这个API实现帧率统计是目前最通用、准确的方案,不需要额外权限,兼容Android 4.1(API 16)及以上所有版本:
import android.view.Choreographer class FpsTracker : Choreographer.FrameCallback { private var lastFrameTimestamp = 0L private var frameCounter = 0 var currentFps = 0f private set fun startTrack() { Choreographer.getInstance().postFrameCallback(this) } fun stopTrack() { Choreographer.getInstance().removeFrameCallback(this) // 重置统计状态 lastFrameTimestamp = 0L frameCounter = 0 } override fun doFrame(frameTimeNanos: Long) { if (lastFrameTimestamp != 0L) { val timeSpan = frameTimeNanos - lastFrameTimestamp frameCounter++ // 间隔满1秒计算一次平均帧率 if (timeSpan >= 1_000_000_000L) { currentFps = frameCounter * 1_000_000_000f / timeSpan frameCounter = 0 lastFrameTimestamp = frameTimeNanos } } else { lastFrameTimestamp = frameTimeNanos } // 注册下一次帧回调,持续统计 Choreographer.getInstance().postFrameCallback(this) } }
使用说明
- 避免在应用后台时运行监听,减少不必要的性能消耗,建议在页面
onResume生命周期调用startTrack()启动统计,在onPause生命周期调用stopTrack()停止统计 - 如果只需要获取屏幕硬件支持的标称刷新率,可以直接通过
context.display.refreshRate获取(Android 12以下版本通过windowManager.defaultDisplay.refreshRate获取),但这个值是屏幕硬件的固定参数,不是应用实际运行时的真实渲染帧率 - 上述方案统计的是当前应用自身的渲染帧率,如果需要获取全局系统帧率,需要系统签名权限,普通第三方应用无权限获取
内容的提问来源于stack exchange,提问作者Somdip Dey
相关产品推荐
相关产品推荐

