savedInstanceState始终为空

这是我的savedInstaceState代码:

@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); } 

日志始终显示“捆绑保存”标签。

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

我在具有两个扩展了ActionBarActivity活动AB的项目中观察到完全相同的症状(报告为问题133394 )。 活动A是主要活动,当从详细视图活动B返回时,我总是在其列表片段的onCreate中为savedInstanceState接收null 。 几个小时后,这个问题就变成了一个伪装的导航问题。

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

  • 鉴于这个答案,我确保片段和活动每个都有唯一的ID集。
  • 没有super调用,不会覆盖onSaveInstanceState
  • Activity AAndroidManifest.xml被指定为acitivy B的父级,同时使用android:parentActivityName属性和早期版本的Android的相应meta-data标签(请参阅“ 提供导航 ”)。

已经没有任何相应的创build代码,如getActionBar() .setHomeButtonEnabled(true) ,活动B在其操作栏中有一个运行后退button( < )。 当点击这个button时,活动A重新出现,但是(a)所有以前的实例状态丢失, (b)总是调用onCreate(c) savedInstanceState总是为null

有趣的是,当我点击提供在仿真器显示底部边缘的后退button(一个打开的三angular形指向左侧)时,活动A就会像剩下的一样重新出现(即其实例状态完全保留),而不会调用onCreate 。 所以导航可能有问题吗?

在阅读更多内容之后 ,我实现了自己的导航指令,以响应活动B中的后退button:

 @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不是新鲜的(因此没有提供保存的实例状态)

如果已设置,并且正在启动的活动已在当前任务中运行,则不会启动该活动的新实例,而是closures其上的所有其他活动,并将此Intent交付给(现在开启顶端)旧活动作为一个新的意图。

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

 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 (见这里 ),这可能不是完整的解决scheme。 另外,不使用NavUtils行为可能相同的解决scheme是简单地调用finish()

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

这两个解决scheme都在我的手中。 我只是猜测原始问题是后退button的稍微不正确的默认实现,它可能与调用某种错过FLAG_ACTIVITY_CLEAR_TOPnavigateUp实现有关。

你有没有检查,如果你有一个Id设置为该视图(如果它是/有…)。 否则,不会调用onSaveInstanceState()。

检查这个链接 。

以这种方式保存的状态不会持续下去。 如果整个应用程序在debugging过程中被杀死,那么bundle在onCreate中将始终为空。

这个IMO是另一个糟糕的Android文档的例子。 这也是为什么市场上的大多数应用程序都没有正确保存状态的原因。

在清单中添加这一行的活动

 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> 

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

编辑 :War_Hero在评论中指出, 关于该主题的文档指出不,它不应该是第一行。

你如何testing它?

Imo最好的testing方法是使用“设置”>“开发人员选项”中的“不要保留活动”标志。 如果您在“设置”中没有“开发者选项”,请参阅启用设备上的开发者选项 。

  1. 打开你的活动
  2. 长按回家
  3. 转到另一个应用程序
  4. 长按回家
  5. 回到你的应用程序

AndroidManifest.xml检查您的活动,如果为true,则删除android:noHistory属性。

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

要进行debugging,请考虑实现onRestoreInstanceState并在此方法中调用Log.d。 然后,在模拟器中,按Ctrl-F11或任何旋转手机。 你打给Log.d的电话应该打。

实现onRestoreInstanceState方法,并在其中放置下面的代码

 Altodo = savedInstanceState.getStringArrayList("todo_arraylist"); 

我发现,当我重写onSaveInstanceState()并实际保存一些数据在Bundle ,实例状态恢复。 否则它不是。