做一个Android FPS计数器

时间:2015-05-29 15:30:33

标签: android frame-rate systrace screen-recording

我试图为任何Android应用做一个FPS计数器。这意味着我没有该应用程序的源代码(我无法修改它或类似的东西,我只有.apk)。

我已经对此进行了大量研究,并且我发现只有一个应用程序执行此操作(它被称为Game Bench,您可以在Google Play上找到它),所以有可能以某种方式。当应用程序启动时,它会显示一个包含手机上所有游戏的列表,您可以选择一个,Game Bench会自动启动它并计算FPS。我需要一个类似的行为。

现在,我要问的是,如果你们中的任何人至少知道如何计算应用程序的FPS(不用编写代码)。做研究我发现了一些模糊的,比如记录屏幕和计算视频的FPS,或以某种方式使用systrace收集的数据计算FPS。但是对于这两个"想法"互联网上的信息非常少。

所以,如果你们有关于这个问题/想法/意见的任何信息,我会很高兴听到他们。谢谢!

1 个答案:

答案 0 :(得分:0)

这是我如何使用Surface View对FPS进行测试的一个例子。 查看Run方法以查看FPS的工作原理。

1:我们在更新前得到时间并渲染到屏幕上。

2:完成所有工作后,我们再次抽出时间。

3:1000毫秒是秒,40 FPS是常态。

4:elaspedTime = startTime - endTime;

5:所以如果elaspedTime低于25,那么它至少要做40 FPS。

6:如果elaspedTime = 5毫秒,则其执行1000/5 = 200 FPS

7:如果在同一个线程上运行更新程序和渲染器,则可以将线程休眠几毫秒。这样你就不会多次更新。

8:希望它有助于这个类是一个基本的游戏类,即使它们在Galaxy S 6上运行它也能保持游戏运行和40 fps。您可能需要进行必要的更改以进一步调整它。 / p>

public class MySurfaceView extends SurfaceView implements Runnable {
    long time = 0, nextGameTick = 0;
    SurfaceHolder myHolder;
    Thread myThread = null;
    boolean myRunning = false;

    public MySurfaceView(Context context) {
        super(context);
        myHolder = getHolder();
    }

    @Override
    public void run() {
        while (myRunning) {
            nextGameTick = System.currentTimeMillis();
            if (!myHolder.getSurface().isValid())
                continue;
            Update();
            Render();
            time = nextGameTick - System.currentTimeMillis();
            time = (time <= 0) ? 1 : time;
            if (time <= 25)
                sleepThread(25 - time);
            Log.d("FrameRate", String.valueOf(1000 / time));
        }
    }

    public void pause() {
        myRunning = false;
        while (true) {
            try {
                myThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        myThread = null;
    }

    public void resume() {
        myRunning = true;
        myThread = new Thread(this);
        myThread.start();
    }

    public void sleepThread(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void Render() {
        // TODO Render to Screen
    }

    private void Update() {
        // TODO Update
    }
}