Reputation: 2297
Frame rate: I'm referring to the rate at which display changes. i.e. Ondraw() is called and the canvas is redrawn.
Is there a default rate for all android devices ? As this rate depends on the processing power of the device , How to find out the frame rate of a device , before starting to program for that mobile device ?
Upvotes: 12
Views: 33663
Reputation: 2373
There is a simple tricky way to find device FPS during runtime.
Just call the following method:
long oneSecondLater=0;
int FPS=0;
int counter=0;
ValueAnimator v_animator;
private void logFPS()
{
oneSecondLater = System.currentTimeMillis()+1000;
v_animator = ValueAnimator.ofFloat(0.0f, 1.0f);
v_animator.setRepeatCount(ValueAnimator.INFINITE);
v_animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
FPS++;
if(System.currentTimeMillis() > oneSecondLater)
{
counter++;
if(counter>1)//ignore the first onAnimationUpdate call (it is not correct)
Log.i("checkFPS","FPS:" + FPS);
FPS=0;
oneSecondLater = System.currentTimeMillis()+1000;
}
}
});
v_animator.start();
}
I log FPS every second, The output of my Logcat was as follows
It works because for ValueAnimator, onAnimationUpdate() method will call according to device FPS;
Upvotes: 2
Reputation: 26
This might be an old question, but for future reference, I found this library named Takt https://github.com/wasabeef/Takt. Takt is Android library for measuring the FPS using Choreographer.
Upvotes: 0
Reputation: 1791
You can use the dumpsys tool provided by Android. To obtain information about the display of the device execute the command:
adb shell dumpsys display
The information about the frame rate of the device is provided in the attribute "mPhys".
You will find something like:
mPhys=PhysicalDisplayInfo{1080x1920, 60.000004 fps, densitiy 3.0,
480.0x480.0 dpi, secure true}
The frame rate of the device is in the second field, in my case is 60.000004 fps
Upvotes: 9
Reputation: 77762
You can't rely on a certain framerate. Android is a using multitasking operating system. If there are some threads running in the background that do some heavy lifting, you might not be able to reach the framerate you want. Even if you're the only active process, the framerate depends on your GPU and CPU, and the clock of each. Maybe the user has a hacked ROM that changes the clock to a custom value.
Some phones might be locked to a certain framerate. The HTC EVO was locked to 30fps for the longest time, until custom ROMs came out that removed that limitation. Newer EVO ROMs also removed that limitation.
I don't know what you're trying to do, but your best bet is to measure the time after each frame and use that delta for your animations. If you're trying to display the FPS, then use a smoothed average.
Upvotes: 2
Reputation: 10859
This may be a follow-up to this question, where I suggested that having a redraw loop that just kept drawing over and over again might be a bit excessive. There may be an api to find out the capabilities of the devices display, but if there is I'm not aware of it. When you're writing your own event loop / thread function you can control the framerate by how often you call your 'draw' method. Typically, I think for most purposes, you would be ok with a refresh rate of 30 or so. If you're writing a fast action game, that needs rapid animation then you may want to run as fast as you can, the more fps, the smoother it will be.
A typical event loop (thread run function) might look something like this:
// define the target fps
private static final int UPDATE_RATE = 30; // Frames per second (fps)
public void run() {
while(running) { // volatile flag, set somewhere else to shutdown
long beginTimeMillis, timeTakenMillis, timeLeftMillis;
// get the time before updates/draw
beginTimeMillis = System.currentTimeMillis();
// do the thread processing / draw
performUpdates(); // move things if required
draw(); // draw them on the screen
// get the time after processing and calculate the difference
timeTakenMillis = System.currentTimeMillis() - beginTimeMillis;
// check how long there is until we reach the desired refresh rate
timeLeftMillis = (1000L / UPDATE_RATE) - timeTakenMillis;
// set some kind of minimum to prevent spinning
if (timeLeftMillis < 5) {
timeLeftMillis = 5; // Set a minimum
}
// sleep until the end of the current frame
try {
TimeUnit.MILLISECONDS.sleep(timeLeftMillis);
} catch (InterruptedException ie) {
}
}
}
Upvotes: 8