如何最好地暂停和恢复surfaceView线程

时间:2013-05-05 04:30:12

标签: android multithreading

我的线程在onPause发生时没有停止,导致“线程已经启动”logcat错误onResume因为我不能运行两个线程实例。如何在此时终止线程?我相信我需要做一些事情:

gameLoopThread.setRunning(false);

但我无法将其添加到我的balloonBasic onPause,我认为上下文是错误的。请帮忙,代码如下所示。 (代码示例非常有用,谢谢)

我的活动:

public class balloonBasic extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(new GameViewBasic(this));
}

public void onResume() {
    super.onResume();
    SoundManager.getInstance();
    SoundManager.initSounds(this);
    SoundManager.loadSounds();
    }

public void onPause() {
    super.onPause();
    //what do I put here?
}
}

我的表面视图:

public class GameViewBasic extends SurfaceView {

...abbreviated declarations...
private static SurfaceHolder holder;
private static GameLoopThreadBasic gameLoopThread;

   public GameViewBasic(Context context) {
         super(context);
         gameLoopThread = new GameLoopThreadBasic(this);
         holder = getHolder();
         holder.addCallback(new Callback() {



                public void surfaceDestroyed(SurfaceHolder holder) 
                {
                    gameLoopThread.setRunning(false);
                }


                public void surfaceCreated(SurfaceHolder holder) {

                       createSprites();
                       mapspritegraphics();

                       gameLoopThread.setRunning(true);
                       gameLoopThread.start();

                }

                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
                {
                }
         });
   }
...abbreviated for brevity....

我的主题:     公共类GameLoopThreadBasic扩展Thread {        私人GameViewBasic视图;        private volatile boolean running = false;

   public GameLoopThreadBasic(GameViewBasic gameViewBasic) {
         this.view = gameViewBasic;
   }
   public void setRunning(boolean run) {
         running = run;
   }

   @Override
   public void run() {
         long ticksPS = 25; // =(1000/fps) ie 25ticksPS = 40fps
         long startTime;
         long sleepTime;

         while (running) {
                Canvas c = null;
                startTime = System.currentTimeMillis();
                try {
                       c = view.getHolder().lockCanvas();
                       synchronized (view.getHolder()) {
                              view.onDraw(c);
                       } 

                } catch (Exception f) {} //
                finally {
                       if (c != null) {
                              view.getHolder().unlockCanvasAndPost(c);
                       }
                } 
                sleepTime = (ticksPS - (System.currentTimeMillis() - startTime));
                try {
                       if (sleepTime > 0)
                              sleep(sleepTime);
                       else
                              sleep(10);
                } catch (Exception e) {}
         }
   }
}

1 个答案:

答案 0 :(得分:4)

我刚刚开始玩游戏,我在早期使用LunarLander作为灵感......但事实证明LunarLander示例代码实际上有这个bug(尝试启动已经运行的线程) ! 下面是在扩展SurfaceView的类中解决问题的方法。我在某个地方找到了解决方案,但我不记得在哪里,因为它是很久以前的。

public void surfaceCreated(SurfaceHolder holder)
{
    if (mMyThreadName.getState() == Thread.State.TERMINATED)
    {
        mMyThreadName = new MyThreadName(xxx);
    }

    mSurfaceIsReady = true;
    mMyThreadName.start();
}

请注意,我还调用了mMyThreadName = new MyThreadName(xxx);在扩展SurfaceView的同一类的构造函数中。我认为我的surfaceDestroyed回调与LunarLander一样,即。除其他外,mSurfaceIsReady在那里设置为false。

修改

Android IllegalThreadStateException in LunarLander

看起来可能有比上面发布的代码更好的解决方案。相反,有可能始终只是在surfaceCreated中实例化线程,而不检查它是否被终止,并且不在其他任何地方实例化它。我没有尝试过第二种方法!

如果我对不起,我可能会误解你的问题。

相关问题