Choreographer监听计算FPS

232 阅读1分钟

前言

Choreographer类实现监听:

public class FrameRateMonitor {
    private static final String TAG = "=FrameRateMonitor=";
    private static final long MONITOR_INTERVAL = 1000;
    private static long lastFrameTimeNanos = 0;
    private static long frameCount = 0;
    private static long monitoringStartTime = 0;
    private static Choreographer.FrameCallback frameCallback;

    /**
     * 开始监听帧率
     */
    public static void startMonitoring() {
        Log.d(TAG, "startMonitoring");
        monitoringStartTime = SystemClock.elapsedRealtime();
        frameCallback = frameTimeNanos -> {
            if (lastFrameTimeNanos != 0) {
                // 两帧之间的耗时,停止监听的可能存在不准(结束的时候过早回调)
                long frameTimeMillis = (frameTimeNanos - lastFrameTimeNanos) / 1000000;
                // 两帧之间的帧率
                float frameRate = 1000f / frameTimeMillis;
                Log.d(TAG, "frameRate:" + frameRate);
                frameCount++;
                long elapsedTime = SystemClock.elapsedRealtime() - monitoringStartTime;
                if (elapsedTime >= MONITOR_INTERVAL) {
                    // 1s内的平均帧率
                    float averageFrameRate = (frameCount / (elapsedTime / 1000f));
                    Log.d(TAG, "Average frame rate in the last minute:" + averageFrameRate + "FPS");
                    frameCount = 0;
                    monitoringStartTime = SystemClock.elapsedRealtime();
                }
            }
            lastFrameTimeNanos = frameTimeNanos;
            Choreographer.getInstance().postFrameCallback(frameCallback);
        };
        Choreographer.getInstance().postFrameCallback(frameCallback);
    }

    /**
     * 停止帧率监听
     */
    public static void stopMonitoring() {
        Log.d(TAG, "stopMonitoring");
        if (frameCallback != null) {
            Choreographer.getInstance().removeFrameCallback(frameCallback);
        }
        lastFrameTimeNanos = 0;
        frameCount = 0;
        monitoringStartTime = 0;
    }
}

帧率优化

  1. 减少视图层级
  2. 使用硬件加速(android:hardwareAccelerated=true)
  3. 异步任务(把一些耗时任务放到子线程,不要小瞧以为一个任务10ms就可以放到主线程,如果这种任务过多累积会造成卡顿)
  4. 内存管理(largeBitmat及时在onDestroy释放)
  5. 尽量使用GPU绘制,它比CPU更高效