Android应用在屏幕方向改变时重置,最佳处理方式是什么?

4

我正在制作一个基本的国际象棋应用程序,以便玩一些各种Android编程元素,到目前为止,我学到了很多东西,但这次我迷失了。

当模拟器的方向改变时,活动会被重置。根据我的研究,每当应用程序暂停/中断时,例如键盘更改,电话呼叫,按下主页键等,都会发生同样的事情。

显然,让国际象棋游戏不断重置是不可行的,因此我再次发现自己需要学习如何解决这个问题。

我的研究提出了一些主要的事情,覆盖我的Activity中的onPaused方法,在我的清单中侦听定位、键盘更改(通过android:configChanges),使用Parcelables或Serialization。

我查阅了很多使用Pacelables的示例代码,但老实说它太令人困惑了。也许明天回来以新鲜的眼睛看会更有益,但现在我越看Parcelables就越觉得它没有意义。

我的应用程序利用一个Board对象,其中包含64个Cell对象(在一个8x8的二维数组中),每个Cell对象都有一个Piece对象,可以是实际的象棋子,也可以为空如果该空间为空。假设我使用Parcelable或Serialization,我假设我需要将每个类(Board、Cell和Piece)进行Parcelize或Serialize。

首先,Parcelable或Serialization是否是解决这个问题的正确方法?如果是,哪种更适合?我是否正确地认为三个对象中的每一个都必须被Parceled/Serialized?最后,有没有人有一个简单易懂的Parcelable教程链接,任何帮助我理解并防止在我的应用程序进一步扩展时出现更多头痛的东西都可以。

任何帮助都将不胜感激。

5个回答

8

在您的清单文件中的<Activity>标签中,您可以添加android:configChanges="orientation|keyboardHidden",这将阻止活动重新加载并在方向更改或键盘隐藏时调用onConfigurationChanged()。

如果您需要在这些事件发生时进行调整,您可以在活动中覆盖onConfigurationChanged(),否则您只需将属性添加到清单文件即可。

类似于:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.myLayout);
}

运行非常良好。


3
Android 的默认事件处理方式是重新创建活动。基本上,如果您正确处理一个进程,那么一切都可以正常工作,不需要手动处理这些事情。 应用程序基础 提供了对活动生命周期的完整概述,但简单来说,您需要在 onSaveInstanceState() 方法中保存您的活动状态,并使用 onCreate(Bundle savedInstanceState) 中获取的 Bundle 来还原您的应用程序状态。
如果您想将类存储在 Bundle 中,最好的选择是实现 Parcelable 接口。然后,要保存您的状态,可以执行以下操作:
protected void onSaveInstanceState(Bundle outState)
{
  super.onSaveInstanceState(outState);
  outState.putParcelable("yourObject", mYourObject);
}

在onCreate方法中,你只需要这样做:
if (savedInstanceState != null)
  mYourObject = savedInstanceState.getParcelable("yourObject");

当然,您可以将对象转换为Bundle已经包含的普通数组表示形式,而不必实现Parcelable接口。基本上,只需在您的对象中添加一个toArray()方法和一个静态方法fromArray()即可。好好尝试一下,看看哪种方法更适合您。

3

或者将这行代码放在你的OnCreate函数中,这样它就不会旋转了。问题解决了。

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

2
为什么这篇帖子会被点赞?这个人想通过在屏幕方向改变时保留应用程序状态来解决问题,而不是将他的应用程序限制在纵向方向。这并没有解决问题,而是忽略了一个问题! - tf.alves

1

在您的Activity类中覆盖onRetainNonConfigurationInstance方法。

在此方法中,您必须返回一个对象,只需将游戏状态捆绑在单个状态对象中并在此方法中返回即可。请确保这仅是一个状态对象,也就是说,它不应该包含任何活动、视图等句柄,否则会导致内存泄漏。

在您的onCreate方法中调用getLastNonConfigurationInstance以获取对象。

您不必担心实现细节(序列化),Android会处理它。

如果您还没有将清单中的启动模式设置为singleTask或singleInstance,请务必这样做,具体取决于哪种更适合您的需求。默认情况下,如果有人按Home键然后回到您的应用程序,它会启动活动的新副本,如果未处理或配置为单个实例,则会运行多个游戏活动的副本。


1

当您保存棋盘状态时,请创建一个int [64]数组,并在每个位置存储相应的棋子。因此,0=空,1=白兵,2=白马等...

当您加载棋盘状态时,请遍历数组并在适当的位置创建相应的棋子对象。

您可以将int [64]转换为字符串以存储在SharedPreferences中,或者与Parcelable一起使用。仅存储所需的最小数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接