问题描述:
我的app中某个界面的Activity是继承FragmentActivity,因为此界面包含两个Fragment。这里我称为
FragmentA和FragmentB吧。在FragmentA和FragmentB中传入了该activity实例,当应用程序运行到该
Activity时,按Home键将该应用程序放置后台运行,使用其他的app。一段时间后,又回到该应用程序,
结果程序crash了。以上就是我的业务场景,说简单点就是Fragment需要与它附属的Activity进行通信。
问题分析:
刚开始遇到该问题时,查看奔溃日志,发现是空指针异常。因为这种场景不多,所以只是简单的加上
非空判断就没在意这个问题了。到后面换了个测试机器,配置不是很好(只有512M运行内存),结果此
问题频繁地出现。
我们看看FragmentActivity源码中的onSaveInstanceState方法:
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable("android:support:fragments", p);
}
}
由上面源码可以看出,FragmentActivity确实在onSaveInstanceState方法里面将Fragment的状态保存
了。
原来Activity切换到后台之后,由于内存不够,此Activity被系统回收了,一段时间之后回到该应用程
序,Activity被重新实例化了。而Activity被系统销毁时,附属在该Activity的Fragment并没有被销毁,在
Activity的onSaveInstanceState里面将Fragment状态保存起来了,所以Activity重新创建了,但是
FragmentA和FragmentB还是之前的,而此时FragmentA和FragmentB所附属的Activity已经被系统回收
了,这次再调用getActivity时返回了null,才导致上面问题的出现。
问题解决:
解决方法其实很简单,我们只要让FragmentActivity被系统回收的时候,不保存Fragment的状态即
可,即在FragmentActivity中重写onSaveInstanceState方法,并且注释掉
super.onSaveInstanceState(outState)就行了。
Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
}