当前位置: 首页 > 知识库问答 >
问题:

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

万俟鸿波
2023-03-14

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

gameLoopThread.setRunning(false);

但是我不能把它添加到我的气球基本暂停中,我认为上下文是错误的。所以请帮忙,代码如下所示。(代码示例会很有帮助,谢谢)

我的活动:

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 扩展线程 { 私有游戏视图基本视图; 私有易失性布尔值运行 = 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个答案

何麻雀
2023-03-14

我前一段时间在做一个游戏,在早期阶段我使用了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 的同一类的构造函数中。我认为我的 surfaceDestroy 回调与 LunarLander 的回调相同,即。mSurfaceIsReady在那里被设置为假,等等。

编辑

LunarLander中的Android IllegalThreadStateException

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

我可能误解了你的问题,如果是的话,我很抱歉。

 类似资料:
  • 问题内容: 我在viewDidAppear中有一个图像,并用以下代码对其进行了动画处理: 我想在点击时暂停动画,如果再次点击它则继续播放动画。 问题答案: 暂停和恢复动画的2个功能,我从这里开始转换为Swift。 我有一个按钮可以暂停或恢复在中初始化的动画:

  • 问题内容: 我声明我已阅读有关线程的内容,但从未使用过。所以我问你:) 我有两个线程:和,其中管理GUI和逻辑。 我将从开始。 然后在绘制GUI时,我将其暂停,以等待到达X点的run方法。 当到达X点进入run方法时,我暂停并继续。 并共享一些变量来管理GUI和逻辑… 我可以做吗?如果是,如何?:) 问题答案: 使用和方法: -使当前线程等待,直到另一个线程调用 该对象的方法。 -唤醒正在该对象的

  • 嗨,我在camel中有一个JMS消费者路由,我的要求是在特定事件时停止/暂停该路由(基于某个字段值),然后使用调度器恢复该路由。为此,我创建了两个路由,一个是我的原始jms消费者路由,另一个是调度程序路由,它们恢复jms消费者路由,虽然我能够暂停路由,但第二个路由不恢复暂停的路由,它显示的状态为已启动。 以下是我的两条路线 请帮助我如何实现上述场景。

  • 问题内容: 我有一个基本的Swing UI,带有一个标记为“播放”的按钮。按下按钮后,标签变为“暂停”。现在,当按下按钮时,它变为“继续”。 在“播放”中,我将实例化并执行一个SwingWorker。我想要的是能够暂停该线程(不要取消该线程),并根据上述按钮按下来恢复它。但是,我不想在doInBackground()中求助于Thread.sleep()。这似乎有点骇人听闻。有什么方法可以阻止运行d

  • 我要做的是暂停< code>KafkaConsumer,如果在使用消息的过程中出现错误。 这是我写的 然后我写了一个REST服务来恢复消费者 现在,我有两个问题。第一个问题:当我打电话给消费者时。来自<code>@KafkaListener</code>注释方法的pause()会发生什么?消费者立即暂停,或者我可以接收到同一主题分区的其他偏移量上的其他消息。例如,我有偏移量为3的“message1

  • 问题内容: 我正在开发游戏,我想创建一个暂停菜单。这是我的代码: 但 仍在运行… 我想在玩家单击暂停菜单时暂停计时器,并在玩家返回游戏时继续运行计时器,但是我如何暂停?请帮帮我。 问题答案: 您需要使其无效并重新创建。然后,如果您使用相同的按钮暂停和恢复计时器,则可以使用bool来跟踪状态: