如何使用 onSaveInstanceState()和 onRestoreInstanceState() ?

我试图保存数据的方向变化。如下面的代码所示,我使用 onSaveInstanceState()onRestoreInstanceState()。我尝试获得保存的值,并检查它是否是正确的值在 onRestoreInstanceState()。但是当我尝试在 onCreate()中使用新值时,我没有新值,而是旧值。

protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("TEXT", user);


}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedUser = savedInstanceState.getString("TEXT");
Log.d("enregistred value", savedUser);


}






public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


int display_mode = getResources().getConfiguration().orientation;


if (display_mode == 1) {


setContentView(R.layout.main_grid);
mGrid = (GridView) findViewById(R.id.gridview);
mGrid.setColumnWidth(95);
mGrid.setVisibility(0x00000000);
// mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);


} else {
setContentView(R.layout.main_grid_land);
mGrid = (GridView) findViewById(R.id.gridview);
mGrid.setColumnWidth(95);
Log.d("Mode", "land");
// mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);


}
Log.d("savedUser", savedUser);
if (savedUser.equals("admin")) { //value 0
adapter.setApps(appManager.getApplications());
} else if (savedUser.equals("prof")) { //value 1
adapter.setApps(appManager.getTeacherApplications());
} else {// default value
appManager = new ApplicationManager(this, getPackageManager());
appManager.loadApplications(true);
bindApplications();
}
}
135109 次浏览
  • onSaveInstanceState()是一种用于在暂停活动之前存储数据的方法。

描述: Hook 允许一个视图生成其内部状态的表示,这个表示稍后可以用来创建具有相同状态的新实例。这种状态应该只包含不持久或以后无法重新构造的信息。例如,您将永远不会在屏幕上存储当前位置,因为当视图的新实例放置在其视图层次结构中时,将再次计算该位置。

  • onRestoreInstanceState()是用于检索该数据的方法。

描述: 当从以前保存的状态重新初始化活动时,在 onStart ()之后调用这个方法,这里在 savedInstanceState 中给出。大多数实现只是简单地使用 onCreate (Bundle)来恢复它们的状态,但是有时候在完成所有初始化之后在这里进行恢复会比较方便,或者允许子类决定是否使用默认实现。此方法的默认实现执行对以前被 onSaveInstanceState (Bundle)冻结的任何视图状态的还原。

考虑一下这个例子:
你的应用程序有3个编辑框,用户在其中输入了一些信息,但是他得到了一个调用,所以如果你不使用上述方法,他输入的所有信息都将丢失。
因此,始终将 Activity 的 onPause()方法中的当前数据保存为 bundle & 在 onResume()方法中调用 onRestoreInstanceState()方法。

请参阅:

请问如何使用 onSavedInstanceState 示例

Http://www.how-to-develop-android-apps.com/tag/onrestoreinstancestate/

当您的活动在先前被销毁之后被重新创建时,您 可以从系统传递的 Bundle 中恢复保存的状态 OnCreate ()和 onRestoreInstanceState () Callback 方法接收包含实例的相同 Bundle 国家信息。

因为 onCreate ()方法被调用是否系统正在创建 你的活动的一个新的实例或重新创建一个以前的,你必须 在尝试读取状态 Bundle 之前检查它是否为空。 如果为空,则系统将创建 活动,而不是恢复以前的一个被摧毁。

static final String STATE_USER = "user";
private String mUser;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mUser = savedInstanceState.getString(STATE_USER);
} else {
// Probably initialize members with default values for a new instance
mUser = "NewUser";
}
}


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(STATE_USER, mUser);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}

Http://developer.android.com/training/basics/activity-lifecycle/recreating.html

这是因为在 onCreate()方法中使用了 savedValue。在 onRestoreInstanceState()方法中更新 savedValue,但是在 onCreate()方法之后调用 onRestoreInstanceState()。你可以选择:

  1. onCreate()方法中更新 savedValue,或者
  2. onRestoreInstanceState()方法中移动使用新 savedValue的代码。

但我建议您使用第一种方法,将代码设计成这样:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


int display_mode = getResources().getConfiguration().orientation;


if (display_mode == 1) {


setContentView(R.layout.main_grid);
mGrid = (GridView) findViewById(R.id.gridview);
mGrid.setColumnWidth(95);
mGrid.setVisibility(0x00000000);
// mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);


} else {
setContentView(R.layout.main_grid_land);
mGrid = (GridView) findViewById(R.id.gridview);
mGrid.setColumnWidth(95);
Log.d("Mode", "land");
// mGrid.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);


}
if (savedInstanceState != null) {
savedUser = savedInstanceState.getString("TEXT");
} else {
savedUser = ""
}
Log.d("savedUser", savedUser);
if (savedUser.equals("admin")) { //value 0
adapter.setApps(appManager.getApplications());
} else if (savedUser.equals("prof")) { //value 1
adapter.setApps(appManager.getTeacherApplications());
} else {// default value
appManager = new ApplicationManager(this, getPackageManager());
appManager.loadApplications(true);
bindApplications();
}
}

在大多数情况下,您不应该需要重写这些方法。 如果要覆盖这些内容,不要忘记调用 super.onSaveInstanceState/super.onRestoreInstanceState

来自 文件的重要提示

默认实现负责每个实例的大部分 UI 中的每个视图调用 View.onSaveInstanceState ()来为您设置 具有 id 的层次结构,并通过保存当前 焦点视图(所有这些视图都由默认实现还原 如果将此方法重写为 保存每个单独视图未捕获的其他信息,则 将可能希望调用默认实现, 否则,准备自己保存每个视图的所有状态。

检查要预览的信息是否是可能具有 ID 的视图的一部分。只有那些有 ID 的才会被自动保留。

如果要保存尚未保存的状态的属性。然后重写这些方法并添加位。

protected void onSaveInstanceState (Bundle outState)


protected void onRestoreInstanceState (Bundle savedInstanceState)

在最新的 SDK 版本中,Bundle 参数不为空,因此只有在保存了 StateIsOrganable 的情况下才调用 onRestoreInstanceState。

但是,OnCreate 也会获取 savedState 参数。但是第一次调用可以为 null,因此需要区分第一次调用和以后的调用。