问题
I'm trying to do an FPS counter for any Android app. That means I don't have the source code for that app (I can't modify it or anything like that, I just have the .apk).
I've researched a lot into this and I've found only one app that does this (it's called Game Bench, you can find it on Google Play), so it is possible somehow. When the app starts, it has a list with all the games on your phone, you choose one and Game Bench automatically starts it and calculates the FPS. I need a similar behaviour.
Now, what I am asking is, if any of you has at least an idea of how I could calculate the FPS of an app (without writing code in it). Doing research I found a few vague ones, like record the screen and calculate FPS of the video, or somehow calculate the FPS using data collected with systrace. But on both these "ideas" there is very few info on the internet.
So please, if you guys have any information about this matter/ ideas/ opinions, I'll be happy to hear them. Thanks!
回答1:
This is an example of how I would bench FPS using a Surface View. Look at the Run method to see how the FPS works.
1: We get the time before update and render to the screen.
2: After all work is done we get the time again.
3: 1000 milliseconds is a second and 40 FPS is the norm.
4: elaspedTime = startTime - endTime;
5: So if elaspedTime is under 25 then its at-least doing 40 FPS.
6: If elaspedTime = 5 milliseconds then its doing 1000 / 5 = 200 FPS
7: You can sleep the thread for a couple milliseconds if you are running the updater and renderer on the same thread. That way you're not updating to many times.
8: Hope it helps this class is a basic game class that keeps the game running and 40 fps even if they are running it on a Galaxy S 6. You would want to make your own necessary changes to tweak it more.
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
}
}
来源:https://stackoverflow.com/questions/30533511/doing-an-android-fps-counter