我一直在安卓SDK平台上工作,现在还不清楚如何保存应用程序的状态。因此,考虑到“你好,Android”示例的这个小的重新设计:

package com.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  private TextView mTextView = null;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextView = new TextView(this);

    if (savedInstanceState == null) {
       mTextView.setText("Welcome to HelloAndroid!");
    } else {
       mTextView.setText("Welcome back.");
    }

    setContentView(mTextView);
  }
}

我认为这对于最简单的情况来说已经足够了,但无论我如何离开应用程序,它总是以第一条消息来响应。

我确信解决方案就像重写onPause之类的东西一样简单,但我已经在文档中翻了大约30分钟,没有发现任何明显的东西。


当前回答

这两种方法都是有用和有效的,都最适合不同的场景:

用户终止应用程序并在稍后重新打开,但应用程序需要重新加载上次会话中的数据,这需要使用持久存储方法,例如使用SQLite。用户切换应用程序,然后返回到原始状态,并希望恢复到他们停止的状态-在onSaveInstanceState()和onRestoreInstanceState(()中保存和恢复捆绑数据(如应用程序状态数据)通常就足够了。

如果以持久方式保存状态数据,则可以在onResume()或onCreate()(或实际上在任何生命周期调用中)中重新加载状态数据。这可能是或可能不是期望的行为。如果您将其存储在InstanceState中的捆绑包中,则它是暂时的,仅适用于存储数据以供在同一用户“会话”中使用(我松散地使用术语“会话”),而不是在“会话”之间使用。

这并不是说一种方法比另一种更好,就像所有事情一样,重要的是了解你需要什么样的行为并选择最合适的方法。

其他回答

这两种方法都是有用和有效的,都最适合不同的场景:

用户终止应用程序并在稍后重新打开,但应用程序需要重新加载上次会话中的数据,这需要使用持久存储方法,例如使用SQLite。用户切换应用程序,然后返回到原始状态,并希望恢复到他们停止的状态-在onSaveInstanceState()和onRestoreInstanceState(()中保存和恢复捆绑数据(如应用程序状态数据)通常就足够了。

如果以持久方式保存状态数据,则可以在onResume()或onCreate()(或实际上在任何生命周期调用中)中重新加载状态数据。这可能是或可能不是期望的行为。如果您将其存储在InstanceState中的捆绑包中,则它是暂时的,仅适用于存储数据以供在同一用户“会话”中使用(我松散地使用术语“会话”),而不是在“会话”之间使用。

这并不是说一种方法比另一种更好,就像所有事情一样,重要的是了解你需要什么样的行为并选择最合适的方法。

savedInstanceState仅用于保存与“活动”的当前实例相关联的状态,例如当前导航或选择信息,这样,如果Android破坏并重新创建“活动”,它就可以恢复原样。请参阅onCreate和onSaveInstanceState的文档

对于更长寿命的状态,请考虑使用SQLite数据库、文件或首选项。请参阅保存持久状态。

Kotlin代码:

保存:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState.apply {
        putInt("intKey", 1)
        putString("stringKey", "String Value")
        putParcelable("parcelableKey", parcelableObject)
    })
}

然后在onCreate()或onRestoreInstanceState()中

    val restoredInt = savedInstanceState?.getInt("intKey") ?: 1 //default int
    val restoredString = savedInstanceState?.getString("stringKey") ?: "default string"
    val restoredParcelable = savedInstanceState?.getParcelable<ParcelableClass>("parcelableKey") ?: ParcelableClass() //default parcelable

如果不想有Optionals,请添加默认值

这是Steve Moseley(由ToolmakerSteve)的回答中的一条评论,它将事情放在了一个角度(在整个onSaveInstanceState与onPause、东成本与西成本传奇中)

@VVK-我部分不同意。退出应用程序的某些方式不会触发onSaveInstanceState(oSIS)。这限制了oSIS的实用性。它的值得支持,操作系统资源最少,但如果应用程序希望将用户返回到他们所处的状态,无论应用程序如何退出时,有必要改用持久存储方法。我使用onCreate检查捆绑包,如果缺少,则检查永久存储。这集中了决策。我可以从崩溃中恢复,或后退按钮退出或自定义菜单项退出,或许多天后,用户重新回到屏幕上ToolmakerSteve九月2015年9月19日10:38

不确定我的解决方案是否受到反对,但我使用绑定服务来保持ViewModel状态。是将其存储在服务的内存中,还是将其持久化并从SQLite数据库中检索,取决于您的需求。这就是任何类型的服务所做的,它们提供诸如维护应用程序状态和抽象公共业务逻辑之类的服务。

由于移动设备固有的内存和处理限制,我以类似于网页的方式处理Android视图。页面不维护状态,它纯粹是一个表示层组件,其唯一目的是显示应用程序状态并接受用户输入。web应用程序架构的最新趋势采用了古老的模型、视图、控制器(MVC)模式,其中页面是视图,域数据是模型,控制器位于web服务后面。同样的模式可以在Android中使用,视图是,嗯。。。View,模型是您的域数据,Controller作为Android绑定服务实现。每当您希望视图与控制器交互时,在开始/恢复时绑定它,在停止/暂停时解除绑定。

这种方法为您提供了实施关注点分离设计原则的额外好处,因为您的所有应用程序业务逻辑都可以移动到您的服务中,这减少了多个视图中的重复逻辑,并允许视图实施另一个重要的设计原则,即单一责任。