我一直在安卓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分钟,没有发现任何明显的东西。


当前回答

我的问题是,我只在应用程序生命周期内需要持久性(即一次执行,包括在同一应用程序内启动其他子活动和旋转设备等)。我尝试了以上答案的各种组合,但在所有情况下都没有得到我想要的答案。最后,对我有用的是在onCreate期间获取savedInstanceState的引用:

mySavedInstanceState=savedInstanceState;

并在需要时使用它来获取变量的内容,如下所示:

if (mySavedInstanceState !=null) {
   boolean myVariable = mySavedInstanceState.getBoolean("MyVariable");
}

如上所述,我使用了onSaveInstanceState和onRestoreInstanceState,但我想我也可以或替代地使用我的方法在变量更改时保存变量(例如,使用putBoolean)

其他回答

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

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

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

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

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

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

有一种方法可以让Android在不执行任何方法的情况下保存状态。只需将此行添加到“活动”声明中的清单:

android:configChanges="orientation|screenSize"

应该是这样的:

<activity
    android:name=".activities.MyActivity"
    android:configChanges="orientation|screenSize">
</activity>

在这里您可以找到有关此属性的更多信息。

建议让Android为您处理,而不是手动处理。

虽然公认的答案是正确的,但有一种更快、更容易的方法可以使用名为Icepick的库在Android上保存“活动”状态。Icepick是一个注释处理器,它负责为您保存和恢复状态时使用的所有样板代码。

对Icepick:

class MainActivity extends Activity {
  @State String username; // These will be automatically saved and restored
  @State String password;
  @State int age;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

与执行以下操作相同:

class MainActivity extends Activity {
  String username;
  String password;
  int age;

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("MyString", username);
    savedInstanceState.putString("MyPassword", password);
    savedInstanceState.putInt("MyAge", age); 
    /* remember you would need to actually initialize these variables before putting it in the
    Bundle */
  }

  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    username = savedInstanceState.getString("MyString");
    password = savedInstanceState.getString("MyPassword");
    age = savedInstanceState.getInt("MyAge");
  }
}

Icepick可以处理任何使用Bundle保存其状态的对象。

科特林

必须重写onSaveInstanceState和onRestoreInstanceState以存储和检索要持久化的变量

生命周期图

存储变量

public override fun onSaveInstanceState(savedInstanceState: Bundle) {
    super.onSaveInstanceState(savedInstanceState)

    // prepare variables here
    savedInstanceState.putInt("kInt", 10)
    savedInstanceState.putBoolean("kBool", true)
    savedInstanceState.putDouble("kDouble", 4.5)
    savedInstanceState.putString("kString", "Hello Kotlin")
}

检索变量

public override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)

    val myInt = savedInstanceState.getInt("kInt")
    val myBoolean = savedInstanceState.getBoolean("kBool")
    val myDouble = savedInstanceState.getDouble("kDouble")
    val myString = savedInstanceState.getString("kString")
    // use variables here
}