开发者

setContentView() inside of a thread

I'm making a simple Android game written in Java.

I have my activity...

public class GameName extends Activity{
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

Inside the "main" layout I have a button that calls a method called "startTheGame":

public void startTheGame(View v) {
theGame = new Panel(this);
    setContentView(theGame);
}

Here is the panel code (simplified)

class Panel extends SurfaceView implements SurfaceHolder.Callback 开发者_C百科{
  public GameThread _thread;
    public Panel(Context context) {
      super(context);
      getHolder().addCallback(this);
      setFocusable(true);
    } 
  ...
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        _thread = new GameThread(getHolder(), this);
        _thread.setRunning(true);
        _thread.start();
    }
 ...
 }

So as you can see I have a "GameThread" class that is started... here it is below:

class GameThread extends Thread {
    private SurfaceHolder _surfaceHolder;
    private Panel _panel;
    private boolean _run = false;

    public GameThread(SurfaceHolder surfaceHolder, Panel panel) {
        _surfaceHolder = surfaceHolder;
        _panel = panel;
    }

    public void setRunning(boolean run) {
        _run = run;
    }
            @Override
    public void run() {
        Canvas c;
        while (_run) {
            c = null;

            try {
                    ...

                    if (health <= 0) {
                        _run = false;

                        //change views?
                        setContentView(R.layout.over);

                    }

                    c = _surfaceHolder.lockCanvas(null);
                    synchronized (_surfaceHolder) {
                        _panel.onDraw(c);                       
                    }

                    ...

                } finally {
                    // do this in a finally so that if an exception is
                    // thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        _surfaceHolder.unlockCanvasAndPost(c);
                    }
                    try {
                        Thread.sleep(60);
                    } catch (Exception e) {
                    }
                }


            }

        }

Hopefully you can see that if the health is <= 0 it stops the thread and I am trying to change to another layout I created called "over".

It just stops the screen from updating (drawing) but I never see the new panel.

I've tried:

GameName cs = ((GameName)getApplicationContext())
cs.setContentView(R.layout.over);

But I'm getting a ClassCastException...

Please Help!


You cannot cast your ApplicationContext to your main Activity (GameName) because this is not the same object. In a certain way, getApplicationContext() does not correspond to the first lauched Activity but to the app itself.

To me you should try to have distinct activities instead of trying to change the layout and the behaviour of a single Activity. It would be more simple for you and it would avoid the kind of issues you are facing. Actually, each setContentView() I see in the code should correspond to a switch.

This way, you would have something like:

  • WelcomeActivity (probably GameName here): select the options of the game and start
  • PlayingActivity: the game itself. This is where the actual gameplay is.
  • GameOverActivity: displays the score, or anything you would like to show once the game ended

This without knowing which kind of game you are doing, but this skeleton should work well with arcade/action, roleplay/adventure or even maze/god-games.


I'd recommend looking into using Handlers. It allows you to safely communicate with the UI thread without worrying which thread you're currently on.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜