6

I'm making a game, and since I'm new to Android, I based the design off of the example LunarLander code. In its design, GameThread.doStart() is called from GameActivity, and the thread then runs everything from its GameThread.run() loop as shown below (much of the code has been removed for clarity):

public class GameActivity extends Activity
{
    public void onCreate(Bundle savedInstanceState)
    {
        gameView = new GameView(this);
        fl = new FrameLayout(this);
        fl.addView(gameView);

        setContentView(fl);

        gameThread = gameView.getThread();
        gameThread.doStart();
    }
}

.

class GameThread extends Thread
{
    public void doStart()
    {
    }

    public void run()
    {
        while (running)
        {
            Canvas c = null;
            try
            {
                c = mSurfaceHolder.lockCanvas();
                // Use canvas
            }
            finally
            {
            }
        }
    }
}

To try to fix some problems I've been running into I tried to put more control in the hands of GameActivity, as shown below:

public class GameActivity extends Activity
{
    public void onCreate(Bundle savedInstanceState)
    {
        gameView = new GameView(this);
        fl = new FrameLayout(this);
        fl.addView(gameView);

        setContentView(fl);

        gameThread = gameView.getThread();

        while (gameThread.isRunning())
        {
            gameThread.run();
        }
    }
}

.

class GameThread extends Thread
{
    public void doStart()
    {
    }

    public void run()
    {
        Canvas c = null;
        try
        {
            c = mSurfaceHolder.lockCanvas();
            // Use canvas
        }
        finally
        {
        }
    }
}

Except when I do that lockCanvas() always returns null, and thus I can't draw anything to the screen. As I said I'm still new to Android so I have no idea why the second case isn't working. Anyone know what's going on or why it's not working?

EDIT: From what I've tested, the surface is never created. During GameView.onResume() I had the activity wait for the surface to be created before moving on with the game, but it waited forever. How come the first instance is the only case where the surface is created?

Jesse Jashinsky
  • 10,313
  • 6
  • 38
  • 63

2 Answers2

3

You are starting a thred in activity on create, while it should be started only when the SurfaceView is created and ready. Check this the second, the SurfaceView example: How can I use the animation framework inside the canvas?

Community
  • 1
  • 1
Lumis
  • 21,517
  • 8
  • 63
  • 67
  • What you're suggesting is what I'm already doing. I just didn't show that code. I'll add it in if you want. – Jesse Jashinsky Aug 03 '11 at 17:56
  • I do not shut down the thread on activity pause, just set a boolean flag so that the thread loop does not call any methods. On resume I reset this flag again and animation continues... If the surface is destroyed then on surfaceCreated will create a new thread next time. – Lumis Aug 05 '11 at 10:03
  • If surface is not created you can detect this and restart the activity. – Lumis Aug 05 '11 at 10:06
  • @Lumis, I am starting my thread when surface view created, but the scenerio is I am setPreviewDisplay(holder) for camera.And when I used getHolder.lockCanvas(), it always return with camera – Kimmi Dhingra Jan 27 '15 at 12:19
0

Start running the thread once the surface gets created. i.e. when you get a callback surfaceCreated(), start the thread.

Code Snippet

public void surfaceCreated(SurfaceHolder holder) {
    thread.setRunning(true);
    thread.start();
}

Shash

Shash316
  • 2,218
  • 18
  • 19