我会尝试解释我的问题:
我的所有片段都在使用setRetainInstance(true) 在我创建的活动中,我正在这样做:
if (savedInstanceState == null) {
fragment = onCreatePane();
fragment.setArguments(intentToFragmentArguments(getIntent()));
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.add(R.id.root_container, fragment, getFragmentTag());
trans.commit();
} else {
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
if ( fragment == null ) {
fragment = getSupportFragmentManager().findFragmentByTag(getFragmentTag());
}
if (fragment == null) {
fragment = onCreatePane();
fragment.setArguments(intentToFragmentArguments(getIntent()));
}
trans.add(R.id.root_container, fragment, getFragmentTag());
trans.commit();
}
因此,当我创建活动并且savedInstance为null时,我创建了Fragment,我设置了它的参数,我开始事务并使用它自己的标记将我的片段添加到事务中(以便稍后再回来)。
用户与活动交互并更改方向。活动被破坏并重新创建(正常活动lifelycle)。所以现在它进入else,片段为null,我做了一个fragment = getSupportFragmentManager().findFragmentByTag(getFragmentTag());
,返回由fragmentManager保存的正确片段。
问题是这个片段持有对已被去除的旧Activity的引用,所以如果我做了fragment.getActivity,它返回null。如何将对acitivy的片段引用更新为新重新创建的Activity?
更新:更准确地说,我在SearchActivity上获取新搜索时调用onNewIntent。所以实际的互动就是这个 - >用户进行搜索 - >搜索显示正确 - >用户更改方向,结果显示正确(如果用户与结果交互,他们没事) - >用户从搜索按钮执行新搜索,并调用SearchActivity的onNewIntent,将新意图分派给具有搜索逻辑的片段。它崩溃了,因为对活动的引用为空
答案 0 :(得分:1)
您何时何地致电getActivity()
?活动参考确实会自动更新,但不会立即更新。在调用onActivityCreated()
后,您应该可以安全地访问它。
答案 1 :(得分:0)
从其他部分if ( fragment == null ) { fragment = getSupportFragmentManager(
中删除空检查......让更新片段与在方向更改时创建的新片段......
答案 2 :(得分:0)
如果setRetainInstance(true) - 是的,那就是解决方案(按标签查找片段,因为再次实例化 - 是错误的方式 - 可能有正在进行的后台例程)。否则,如果你有setRetainInstance(false),问题就可以回来了。 我有类似的。我的情况 - 因为我使用了Loader(在后台)。解决方案很简单:在片段的onDestroy()方法中销毁片段的加载器。
答案 3 :(得分:0)
在你的baseAcvivity中,你可以覆盖onSaveInstanceStat来解决这个问题:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//solution of fragment.getActivity() is null
outState.remove("android:support:fragments");
}