在一个活动A和B扩展了两个项目中,我观察到了完全相同的症状(报告为问题133394)。活性甲是主要的活性,我总是接收用于在其列表片段从一个详细视图活动返回时乙。几个小时后,这个问题以变相的导航问题暴露给我。ActionBarActivitynullsavedInstanceStateonCreate
以下内容可能与我的设置有关,并且来自此页面上的其他答案:
- 有了这个答案,我确保每个片段和活动都有唯一的ID集。
- 没有
onSaveInstanceState没有super呼叫的覆盖。
- 活动A被指定为A中的活动B的父级
AndroidManifest.xml,同时使用android:parentActivityName属性和meta-data早期Android版本的相应标签(请参见“提供导航”)。
getActionBar() .setHomeButtonEnabled(true)活动B已经没有任何相应的创建代码(如),在其操作栏中有一个正常的后退按钮(<)。轻按此按钮后,活动A重新出现,但(a)所有先前实例状态都丢失,(b) onCreate始终被调用,并且(c) savedInstanceState始终null。
有趣的是,当我点击仿真器显示屏底部边缘处的后退按钮(指向左侧的空心三角形)时,活动A再次出现,就像它离开时一样(即实例状态完全保留),而没有调用onCreate。因此,导航可能有问题吗?
经过多看书,我实现了我自己的导航指令响应在活动的后退按钮自来水运行乙:
@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)该方法允许我们通过设置标志来修改导航意图,以明确指示活动A并非重新开始(因此未提供已保存的实例状态)FLAG_ACTIVITY_CLEAR_TOP:
如果已设置,并且正在启动的活动已在当前任务中运行,那么与其启动该活动的新实例,不如关闭该活动之上的所有其他活动,并将此Intent传递给(现在顶部)将旧活动作为新的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的其他情况下,这可能不是完整的解决方案(请参见此处)。另外,一种不使用行为的可能相同的解决方案NavUtils是简单地调用finish():
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
两种解决方案都在我手中。我只是在推测原始问题是后退按钮的默认实现稍有不正确,并且可能与调用某种navigateUp未命中的实现有关FLAG_ACTIVITY_CLEAR_TOP。