SavedInstanceState 始终为 null

这是我保存的 InstaceState 代码:

@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
savedInstanceState.putStringArrayList("todo_arraylist", Altodo);
Log.v("bundle", "Saved");
super.onSaveInstanceState(savedInstanceState);
}




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


if (savedInstanceState != null)
{
Altodo = savedInstanceState.getStringArrayList("todo_arraylist");
Log.v("bundle", "Restored");
}
else
{
Log.v("bundle", "null");
}


setContentView(R.layout.main);
}

日志总是显示“ bundle save”标记。

但在 onCreate方法中,SavedInstanceState始终为空。

64524 次浏览

你怎么测试?

Imo 测试它的最好方法是使用“ Don’t keep activity”-标志在设置 > 开发者选项中。如果在设置中没有开发人员选项,请参见 启用设备上开发人员选项

  1. 打开你的活动
  2. 长按回家
  3. Go to another application
  4. 长按回家
  5. 回到你的申请上

要调试,请考虑实现 onRestoreInstanceState 并在此方法中调用 Log.d。然后,在模拟器中,按 ctrl-F11或其他键来旋转手机。您对 Log.d 的调用应该被命中。

super.onSaveInstanceState(savedInstanceState);不应该是你重写的第一行吗?

编辑 : War _ Hero 在评论中指出,关于这个主题的文件表示不,它不应该是第一行。

实现 onRestoreInstanceState的方法 然后放在代码下面

Altodo = savedInstanceState.getStringArrayList("todo_arraylist");

是否检查了该视图的 Id 设置(如果视图是/已经...)。OnSaveInstanceState ()不会以其他方式调用。

看看这个 链接

以这种方式保存的状态不会持久化。如果整个应用程序像您在调试期间所做的那样被终止,那么该包在 onCreate中将始终为 null。

这个 IMO 是另一个糟糕的 Android 文档的例子。这也是为什么市场上的大多数应用程序不能正确地实现保存状态(根本不能)。

I observed the exact same symptoms (reported as 第133394期) in a project with two Activities A and B that extend ActionBarActivity. Activity A is the main activity, and I always receive null for savedInstanceState in onCreate of its list fragment when returning from a detail view activity B. After many hours, this problem exposed itself to me as a navigation issue in disguise.

以下内容可能与我的设置有关,并且来自本页的其他答案:

  • 给定 this的答案,我确保片段和活动都设置了惟一的 ID。
  • 没有 super调用就不能覆盖 onSaveInstanceState
  • 活动 AAndroidManifest.xml中指定为活动 B的父级,使用早期版本 Android 的 android:parentActivityName属性和相应的 meta-data标记(参见“ 提供导航”)。

已经没有任何相应的创建代码,如 getActionBar() .setHomeButtonEnabled(true),活动 B有一个功能的后退按钮(<)在其行动栏。当点击这个按钮时,活动 A重新出现,但是 (a)所有以前的实例状态都丢失了,(b) onCreate总是被调用,而 .setHomeButtonEnabled(true)0 savedInstanceState总是 null

有趣的是,当我点击模拟器显示器底部边缘提供的后退按钮(一个指向左边的开放三角形)时,活动 A在没有调用 onCreate的情况下重新出现,就像它离开时一样(即它的实例状态完全保留)。也许导航系统出了问题?

更多的阅读之后,我实现了我自己的导航指令来响应活动 B中的后退按钮:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home)
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}

与恢复活动 A的实例状态相关的内容没有改变。NavUtils还提供了一个方法 getParentActivityIntent(Activity)navigateUpTo(Activity, Intent),它允许我们通过设置 FLAG_ACTIVITY_CLEAR_TOP标志来修改导航意图,以明确地指示活动 A没有重新启动(因此没有保存实例状态) :

如果设置了,则正在启动的活动已经在 current task, then instead of launching a new instance of that 活动,所有其上的活动将被关闭和 这个意图将作为一个 新意图。

在我的手中,这解决了丢失实例状态的问题,看起来像:

public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(this, intent);
return true;
}
return super.onOptionsItemSelected(item);
}

请注意,在其他情况下,这可能不是完整的解决方案,用户可以从不同的任务中直接切换到活动 B(参见 给你)。另外,在不使用 NavUtils的行为中,一个可能相同的解决方案是简单地调用 finish():

public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}

两种解决方案都在我手中。我只是推测最初的问题是后退按钮的默认实现稍有不正确,这可能与调用某种遗漏了 FLAG_ACTIVITY_CLEAR_TOPnavigateUp的实现有关。

in Manifest add this line for activities

android:launchMode="singleTop"

例如:

<activity
android:name=".ActivityUniversity"
android:label="@string/university"
android:launchMode="singleTop"
android:parentActivityName="com.alkhorazmiy.dtm.ActivityChart">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.alkhorazmiy.dtm.ActivityChart" />
</activity>

Check your activity in AndroidManifest.xml and remove android:noHistory property if is true.

<activity
// ....
android:noHistory="false" />

I found that when I override onSaveInstanceState() and actually save some data in the Bundle, instance state is restored. Otherwise it's not.

我也是这么做的。我没有在 onCreateView 方法上处理 savedInstanceState Bundle,而是在 onCreate 方法上处理它,并将传递的值设置为一个全局变量,然后在 onCreateView 方法上访问这个变量。 希望能有帮助。

Https://developer.android.com/guide/topics/manifest/activity-element#lmode

从这里你可以看到‘类似地,如果你导航到当前堆栈上的一个活动,行为是由父活动的启动模式决定的。也许你处于“标准”模式。

I was able to solve it with:

@Override public boolean onSupportNavigateUp()
{
onBackPressed();
return true;
}

仍然在清单中设置了父级。所以当你按下向上导航按钮时,它就像是后退按钮。