在 onResume/onPause 中重新启动/暂停线程

发布于 2024-11-29 19:50:21 字数 390 浏览 4 评论 0原文

我有一个使用 SurfaceView 实现来显示对象的游戏。 我有一个线程,它会不时地将 SurfaceView 绘制到屏幕上。 游戏正在完全运行。 不幸的是,它需要在游戏中断时具有暂停功能。 好吧,我知道我需要操作 onResumeonPause

但我做不到。该错误将我带回到 SurfaceCreated ,我在其中启动线程,告诉我线程已经启动。我尝试分别在 onResumeonPause 上使用 resumesuspend,但没有任何变化。

我怎样才能实现这个目标? 我已经完成了如何使用文件 I/O 处理来保存对象位置。

提前致谢。

I'm have a game that's uses SurfaceView implementation to display the objects.
I have a thread which draws the SurfaceView time-to-time to the screen.
The game is running completely.
Unfortunately, it needed to have a pause function whenever the game is interrupted.
Well, I know that I need to manipulate onResume and onPause.

But I can't get it right. The error points me back to surfaceCreated where I start the thread telling me that the thread has started already. I tried using the resume and suspend on the onResume and onPause respectively but nothing changed.

How can I achieve this?
I have already done how the objects location would be save using File-I/O handling.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雪花飘飘的天空 2024-12-06 19:50:21

这就是我所做的:

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
           if (thread.getState() == Thread.State.TERMINATED){
              CreateThread(getHolder(),getContext());
           }
           thread.setRunning(true);
           thread.start();
    }
  • 在 CreateThread 中,您应该有 thread = new MyThread(...);
  • setRunning (boolean mRun) 使用布尔值来启动/停止运行函数(我想我是受到 LunarLander 的启发);

如果您想正确使用 onPause/onResume,请勿将线程使用的变量放入线程内(如 LunarLander 中所做的那样)。我建议你这样做:

// Variables declarations

public MyGameThread CreateThread(...){
thread = new MyGameThread(holder, context, new Handler() {
// and so on....
});
}

当你通过onPause/onResume时,你的线程将被销毁并重新启动,但如果你将变量放在它外面,你可以在之后继续使用它们。

如果您有重要的内容需要保留,请使用以下选项之一:

  • SharedPreferences:将在本地创建并保存一个 xml,其中包含即使在应用程序结束后仍然存在的变量;
  • 如果您要管理超过 5-10 个变量,则使用 SQL 数据库,因为在这种情况下,使用前一个选项会很困难。

This is what I did:

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
           if (thread.getState() == Thread.State.TERMINATED){
              CreateThread(getHolder(),getContext());
           }
           thread.setRunning(true);
           thread.start();
    }
  • In CreateThread you should have the thread = new MyThread(...);
  • the setRunning (boolean mRun) use a boolean to start/stop the run function (I think I was inspired by the LunarLander);

If you want to use properly the onPause/onResume don't put the variables used by your thread inside the thread (as done in LunarLander). I suggest you to do like that:

// Variables declarations

public MyGameThread CreateThread(...){
thread = new MyGameThread(holder, context, new Handler() {
// and so on....
});
}

When you pass through the onPause/onResume, your thread will be destroyed and reneweled but if you put your variables outside it, you can continue to use them after.

If you have something important to preserve, use one of this options:

  • SharedPreferences: an xml will be created and saved locally with variables that persist even after the end of the app;
  • a SQL db if you would manage more than 5-10 variables because in this case the use of the former option would be difficult.
停顿的约定 2024-12-06 19:50:21

实际上不建议您自己停止线程,stop() 方法已被弃用。最简单的解决方案是在线程的 run() 方法内的 while 循环中使用标志。当您需要“停止”线程时,只需将标志设置为 false,线程将不再执行任何操作,尽管它会继续运行。 Android 会在需要时停止你的线程。希望这有帮助。

Actually it's not recommended to stop a thread by yourself, the stop() method is deprecated. The simplest solution is to use a flag in your while loop inside the thread's run() method. When you need to "stop" the thread, you just drop the flag to false and the thread won't do anything anymore, despite it will keep running. Android will stop your thread when it's needed. Hope this helps.

后知后觉 2024-12-06 19:50:21

不知道代码的来龙去脉。

要“暂停”线程,您可以实现如下功能:

while(! this.isInterrupted())
    if(!paused)
    {
        ... Do something ...
    } else { try { Thread.sleep(100) } catch (InteruptedException ie) {} }

这取决于 Do Something 是否使您的表面视图无效或以其他方式控制应用程序中的进度。 paused 的访问器应该允许您暂停和恢复线程,而不会陷入架构的任何其他部分。

Without knowing the ins and outs of your code.

To "Pause" a thread you can implement functionality like so:

while(! this.isInterrupted())
    if(!paused)
    {
        ... Do something ...
    } else { try { Thread.sleep(100) } catch (InteruptedException ie) {} }

This is depending if Do something is invalidating your surface view or otherwise controlling progression in your app. An accessor to paused should allow you to pause and resume your thread without getting caught up in any other bit of architecture.

自此以后,行同陌路 2024-12-06 19:50:21

我不确定你在这个问题中是否有一个或两个线程,我假设是 2。当你调用 onPause 时,你需要做三件事:

1 - Save the state of the application (all game variables, states, etc)
2 - Kill the surfaceView by calling suspend.
3 - Kill the other thread (we'll call it Thread B).

我认为杀死线程 B 是你的问题。您想要中断线程并告诉它退出,否则当您调用 onPause 时,您的线程仍将执行其操作。然后,当您返回游戏时,线程将尝试再次创建,这会导致问题。有两种方法可以正确终止线程:

  • 在线程的 while() 循环中,有一个布尔值“run”,while(run) 将执行代码。当您将 run 更改为 false 时,线程将退出。
  • 如果你的线程休眠了(我认为它可能会休眠,因为它是一个游戏并且将在运行时运行),捕获 InterruptedException 然后退出。当你想杀死线程时,你向线程抛出异常。

第一个是迄今为止最简单的。

I'm unsure if you've got one or two threads in this question, I'm assuming 2. You need to do three things when you call onPause:

1 - Save the state of the application (all game variables, states, etc)
2 - Kill the surfaceView by calling suspend.
3 - Kill the other thread (we'll call it Thread B).

Killing of Thread B is your problem I think. You want to interrupt the thread and tell it to quit, or else when you call onPause your thread will still be doing its thing. Then, when you go back into the game, the thread will try to be created again which causes the problem. There are 2 ways to kill a thread properly:

  • In the while() loop of your thread, have a boolean 'run' which while(run) will execute the code. When you change run to false, the thread exits.
  • If your thread sleeps (I assume it might do since its a game and will be running w.r.t time), catch the InterruptedException and then quit there. When you want to kill the thread, you throw the exception to the thread.

The first one is by far the easiest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文