[android] game becomes slower after screen turnoff

Started by
1 comment, last by sheep19 11 years, 7 months ago
I'm making a game on android 2.2 and I'm not using OpenGL.

Here is my problem:

Normally, my update loop runs every 60ms (dt = ~60) - I print it on the screen of the phone (HTC One X - not the emulator).
When I lock the phone by pressing the power button and the unlock it (to resume the game),
dt is more than 300ms !!!

This makes it look very ugly - animations move too fast.

Why is that happening? Why does it become slower?

EDIT: This does not happen if I press the HOME button and then resume the game. It happens only in the situation stated above.

Below you can see the base class I am using, which contains the update/draw thread.



package com.greenbits.RiverCross;
import java.io.Serializable;
import android.content.Context;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
abstract class Screen extends SurfaceView implements SurfaceHolder.Callback, Serializable
{
private boolean initialized = false;

private DrawThread drawThread;
private int screenWidth, screenHeight;

public Screen(Context context)
{
super(context);

getHolder().addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
screenWidth = width;
screenHeight = height;

drawThread = new DrawThread(getHolder(), this);

Log.v("Screen", "surfaceChanged()");

// initialize only the first time (when the screen is created)
if( !initialized )
{
init(); // call user's init()
initialized = true;
}

start(); // start running!
}

/**
* This is where initializations and memory allocations should happen
*/
protected abstract void init();

/**
* When this function is called, the drawThread will start running
*/
private final void start()
{
if( drawThread != null )
drawThread.start();
else
Log.v("Screen", "Screen.start() : can't call drawThread.start() because it is null");
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
Log.v("Screen", "surfaceCreated()");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.v("Screen", "surfaceDestroyed()");

boolean retry = true;
drawThread.running = false;

while (retry)
{
try
{
drawThread.join();

retry = false;
}
catch (InterruptedException e)
{
}
}
}

@Override
abstract public void onDraw(Canvas canvas);

abstract public void update(float dt);

/**
* Perform un-initializations here, close files etc.
*/
abstract public void dispose();

public int screenWidth() { return screenWidth; }
public int screenHeight() { return screenHeight; }

private static class DrawThread extends Thread
{
private SurfaceHolder surfaceHolder;
private Screen screen;
public boolean running = true;

public DrawThread(SurfaceHolder _surfaceHolder, Screen _screen)
{
surfaceHolder = _surfaceHolder;
screen = _screen;
}

public void run()
{
Canvas c;
long then, now;
float dt;
then = now = System.currentTimeMillis();

while( running )
{
// update
now = System.currentTimeMillis();
dt = (now - then) / 1000.0f;
screen.update(dt);
then = now;

// draw
c = null;
try
{
c = surfaceHolder.lockCanvas();

if( c != null )
{
synchronized(surfaceHolder)
{
screen.onDraw(c);
}
}
}
finally
{
if( c != null )
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
Advertisement
Your two lines are suspect:

now = System.currentTimeMillis();
dt = (now - then) / 1000.0f;

Whenever something happens that causes a stall, such as the device going to sleep or heavy processor load, you are going to have extremely high time difference.

One solution for this type of problem is to cap the maximum time difference.

if(dt > kMaxAllowedTimeDifference)
dt = kMaxAllowedTimeDifference;

Your two lines are suspect:

now = System.currentTimeMillis();
dt = (now - then) / 1000.0f;

Whenever something happens that causes a stall, such as the device going to sleep or heavy processor load, you are going to have extremely high time difference.

One solution for this type of problem is to cap the maximum time difference.

if(dt > kMaxAllowedTimeDifference)
dt = kMaxAllowedTimeDifference;


Thank you for your reply, I'll try it later!
However, the extremely high difference wouldn't be for just one frame? Correct me if I'm wrong.

This topic is closed to new replies.

Advertisement