当 Activity 停止和恢复时保存 SurfaceView 的状态

发布于 2024-11-30 09:11:09 字数 399 浏览 0 评论 0原文

我有一个带有 SurfaceView 的 Activity,由游戏引擎(线程)管理。我将重写 onCreate 和 onSaveInstanceState 来管理线程的保存/恢复状态。

当从该 Activity 的菜单访问首选项屏幕时,该 Activity 将经历其生命周期直至 onStop;当首选项屏幕关闭时,Activity 在 onResume 处再次启动,因此 onCreate 不会发生。然而,该线程处于 TERMINATED 状态,因此无法恢复。

是的,我可以创建一个新的线程实例——但是如何恢复状态呢?我也尝试重写 onRestoreInstanceState,但经过快速测试并更彻底地阅读后,我意识到在这种情况下不会调用它,因为它是在 onStart 和 onResume 之间调用的。

处理这个问题的最佳方法是什么?

I have an Activity with a SurfaceView that is managed by a game engine (thread). I'm overriding the onCreate and the onSaveInstanceState for managing the save/restore state of the thread.

When the preferences screen is accessed from the menu of that Activity, that Activity goes through its lifecycle to onStop; when the preferences screen is closed, the Activity starts again at onResume, so onCreate does not happen. The thread however is in a state of TERMINATED and therefore cannot be resumed.

Yes, I can just create a new instance of the thread--but how can I restore the state? I tried overriding onRestoreInstanceState as well, but after a quick test and reading a little more thoroughly I realized that it's not called in this situation because it's called between onStart and onResume.

What's the best way to handle this?

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

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

发布评论

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

评论(2

羁绊已千年 2024-12-07 09:11:09

我认为您确实需要定位 onSaveInstanceStateonRestoreInstanceState 或使用 onCreate 功能来执行此操作(onRestoreInstanceStateonStart 之后调用,而 onCreateonStart 之前调用 - 因此您需要使用 onCreate 方式做事情,虽然我会列出如下)

将您的状态保存在 Activity 的 onSaveInstanceState 中 - 您可能需要将 getter 方法写入 SurfaceView 类:

protected void onSaveInstanceState(Bundle outState) {
  outState.putInt(YourSurfaceViewClass.SOME_ID, surfaceViewClass.getVar());
  super.onSaveInstanceState(saveBundle);
}

并恢复 onCreate 中的值:

public void onCreate(Bundle savedInstanceState) {
  if (savedInstanceState != null){
    value = savedInstanceState.getInt(YourSurfaceViewClass.SOME_ID);
  }
}

restoreInstanceState

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    value = savedInstanceState.getInt(YourSurfaceViewClass.SOME_ID);
}

当您访问首选项屏幕时将调用这些方法,然后使用onCreate 恢复线程的状态。

I think you do need to target the onSaveInstanceState and either onRestoreInstanceState or use the onCreate functionality to do it (onRestoreInstanceState is called after onStart, whereas onCreate is called before onStart - so you'll need to use the onCreate way of doing things, although I'll list both below)

Save your state in the onSaveInstanceState of your activity - you may need to write getter methods in to your surfaceView class:

protected void onSaveInstanceState(Bundle outState) {
  outState.putInt(YourSurfaceViewClass.SOME_ID, surfaceViewClass.getVar());
  super.onSaveInstanceState(saveBundle);
}

And restore the values in onCreate:

public void onCreate(Bundle savedInstanceState) {
  if (savedInstanceState != null){
    value = savedInstanceState.getInt(YourSurfaceViewClass.SOME_ID);
  }
}

or restoreInstanceState:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    value = savedInstanceState.getInt(YourSurfaceViewClass.SOME_ID);
}

These methods will be called when you access the preferences screen and then use onCreate to restore your thread's state.

原谅过去的我 2024-12-07 09:11:09

问题似乎出在我的应用程序的肮脏设计上。由于游戏引擎本身正在扩展 Thread 类并自动设置为TERMINATED,因此当前设计的唯一选择是向surfaceCreated 方法添加逻辑。在那里,我可以检查线程的状态:

如果它是TERMINATED,我可以创建一个Bundle并将其传递给我的引擎的 saveState 方法。获得状态后,我将线程设置为新的游戏引擎线程并传入最近保存的 Bundle。我认为继续正常(启动线程)。

这是可行的,但最好的方法是将实际的线程逻辑移动到一个单独的类中。由于游戏引擎实际上并未被清除,我只会创建一个新的 Thread 实例,而不是重新创建整个游戏引擎,所以这就是我要做的。

The problem seems to be with the dirty design of my app. Since the game engine itself is extending the Thread class and automatically being set to TERMINATED, my only option with the current design is to add logic to the surfaceCreated method. In there, I can check the state of the thread:

If it's TERMINATED, I can create a Bundle and pass it to my engine's saveState method. Once I have the state, I make the thread a new game engine thread and pass in the recently saved Bundle. I think continue as normal (start the thread).

This works, but the best way would be to move the actual Thread logic to a separate class. Since the game engine isn't actually being cleared, I would just be creating a new Thread instance instead of recreating the entire game engine, so this is what I'll do.

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