Android中的配置更改以及在实例状态下保存哪些变量

Android中的配置更改以及在实例状态下保存哪些变量,android,configuration,instance,Android,Configuration,Instance,我试图更好地理解配置更改和实例状态 现在我知道,旋转屏幕之类的操作被视为配置更改,它会破坏并重新创建活动。有时这意味着如果您不小心,可能会丢失值(例如,如果您有一个数字列表,当您旋转屏幕时,该列表被重置为所有0) 通常有一些方法可以用于保存和还原值,例如onSaveInstanceState,或onRestoreInstanceState,或者检查onCreate方法中的savedInstanceState是否为空,等等,以便在发生更改时不会丢失任何内容 我的问题是: 是否需要考虑多种类型的配置

我试图更好地理解配置更改和实例状态

现在我知道,旋转屏幕之类的操作被视为配置更改,它会破坏并重新创建活动。有时这意味着如果您不小心,可能会丢失值(例如,如果您有一个数字列表,当您旋转屏幕时,该列表被重置为所有0)

通常有一些方法可以用于保存和还原值,例如
onSaveInstanceState
,或
onRestoreInstanceState
,或者检查
onCreate
方法中的
savedInstanceState
是否为空,等等,以便在发生更改时不会丢失任何内容

我的问题是:

  • 是否需要考虑多种类型的配置更改?例如,如果我让我的应用程序即使在屏幕旋转的情况下也能按预期工作,这是否也意味着它将在其他形式的配置更改中继续并按预期工作

  • 如何知道应该将哪些变量保存到实例状态变量中,以及在发生配置更改时自动保留哪些变量?将所有成员变量存储在实例状态下的
    onSaveInstanceState
    中,然后在
    onRestoreInstanceState
    中重新应用它们,这是一种良好的做法吗

  • 当Android操作系统内存不足并且需要终止一些进程时,可以调用onSaveInstanceState和onRestoreInstanceState。例如,如果您的应用程序进入后台并在稍后恢复,则可以调用这些方法

  • 活动会自动保存所有视图。例如,EditText的文本和复选框的选中状态将在配置更改后自动保存和恢复。活动的所有其他数据(包括实例变量)应由您使用onSaveInstanceState和onRestoreInstanceState方法手动保存

  • 例如,如果我让我的应用程序即使在屏幕旋转的情况下也能按预期工作,这是否也意味着它将在其他形式的配置更改中继续并按预期工作

    一般来说,是的。我更愿意这样说:一个良好实现的配置更改方法将处理所有可能的配置更改

    因此,例如,如果用户运行您的应用程序,按HOME键,进入设置,更改其区域设置,然后通过概览屏幕(又称最近的任务列表)返回到您的应用程序,则您最重要的活动将发生配置更改。这里的目标是加载新的字符串资源和内容,以反映新选择的语言。但是,如果您在保存的实例状态
    Bundle
    中保存一些面向用户的字符串,并在新活动中简单地使用该字符串,而不是再次调用
    getString()
    ,那么您将拥有旧语言的值

    许多开发人员只考虑方向的改变。通常,如果您处理方向更改,所有其他配置更改都将“免费”处理。但是,情况并非总是如此,这就是为什么你需要仔细考虑的原因

    如何知道应该将哪些变量保存到实例状态变量中,以及在发生配置更改时自动保留哪些变量

    “自动保存”的主要内容包括:

    • 用于启动活动的
      意图

    • 用户界面小部件中的用户可变状态(例如,
      EditText
      )中的文本。。。假设您没有覆盖
      onSaveInstanceState()
      或链接到超类实现

    如果您使用的是片段,那么在配置更改时,您的片段将被保留(即使用的相同实例)或重新创建(即使用的相同类的新实例)

    不自动处理的是活动的任何字段/数据成员。您需要决定的事项:

    • 这是我在配置更改过程中需要保留的内容,还是只是在新活动中重建内容的缓存

    • 这是我可以合理地放入已保存实例状态
      包中的东西,还是它的大小(例如
      位图
      )或数据类型(例如
      套接字
      )无法保持在该状态?对于这些,除了保存的实例状态
      Bundle
      (保留片段、持久化数据等)之外,还需要采用其他技术


    因此,基本上,作为成员的任何非视图数据结构(如字符串、整数、列表、自定义对象等)都需要手动保存/恢复?这是否也意味着让所有“我的对象”实现可包裹性是一种好做法?@SeanHill,你已经做到了!并非所有视图,TextView的文本将重置为初始值(来自xml文件)。@0X0nosugar这是一个很好的观点。如果以编程方式更改TextView的文本,它将不会自动还原。对于位图之类的内容,我不能将其应用于ImageView以使其保持不变吗?作为类的私有成员的自定义对象呢?我假设您必须始终考虑这些问题,或者让它们实现Parcelable,或者使用较慢的Serializable(不需要类AFAIK中的所有额外代码)?@SeanHill:“我不能将其应用于ImageView以使其持久化吗?”--不。用户不能直接将图像放入
    ImageView
    中。这不是“用户可变状态”,因此内置的
    onSaveInstanceState()
    实现会忽略它,就像它忽略可见性、启用/禁用等内容一样。如果用户可以自己更改状态(例如,选中一个
    复选框,滑动一个
    SeekBar
    ),那么这种状态很有可能由Android处理(t