Activity后台运行一段时间回来crash问题的分析与解决

最近作项目的时候碰到一个棘手的问题,花了很多时间才找到缘由并解决。特此记录这个被我踩过的坑,但愿其余朋友遇到此问题不要调到这坑里去了。html

问题描述:android

      一、背景:个人app中某个界面的Activity是继承FragmentActivity,由于此界面包含两个Fragment。这里我称为FragmentA和FragmentB吧。在Activity中有个刷新按钮,用来刷新ViewPager当前Fragment内容的刷新。点击Activity的刷新按钮以后,刷新按钮须要有简单的旋转动画,等Fragment里面的刷新结束以后,会使用getActivity通知Activity结束刷新按钮的刷新动画。以上就是个人业务场景,说简单点就是Fragment须要与它附属的Activity进行通讯。app

  二、问题:当应用程序运行到该Activity时,按Home键将该应用程序放置后台运行,去其余app转转。一段时间后,又回到该应用程序,仍是在以前的那个Activity。这时我想刷新一下Fragment里面的内容,点击了Activity界面上的刷新按钮,结果程序crash了。ide

 

问题分析:post

  刚开始遇到该问题时,查看奔溃日志,发现是空指针异常。由于这种场景很少,因此只是简单的加上非空判断就没在乎这个问题了。到后面换了个测试机器,配置不是很好(只有512M运行内存),结果此问题频繁地出现,开始引发个人重视了。因为经验不是很足,此问题不知道怎么重现,因此很难找出问题的根本缘由。后来终于在网上找到了一篇和我遇到一样问题的朋友的帖子,才知道出现这个问题的缘由所在。测试

  原来Activity切换到后台以后,因为内存不够,此Activity被系统回收了,一段时间以后回到该应用程序,Activity被从新实例化了。而Activity被系统销毁时,附属在该Activity的Fragment并无被销毁,在Activity的onSaveInstanceState里面将Fragment状态保存起来了,因此Activity从新建立了,可是FragmentA和FragmentB仍是以前的,而此时FragmentA和FragmentB所附属的Activity已经被系统回收了,此次再调用getActivity时返回了null,才致使上面问题的出现。动画

  咱们看看FragmentActivity源码中的onSaveInstanceState方法:spa

1 protected void onSaveInstanceState(Bundle outState)
2    {
3      super.onSaveInstanceState(outState);
4      Parcelable p = mFragments.saveAllState();
5      if (p != null) {
6        outState.putParcelable("android:support:fragments", p);
7     }
8    }

  由上面源码能够看出,FragmentActivity确实在onSaveInstanceState方法里面将Fragment的状态保存了。.net

 

问题解决:指针

  知道问题的缘由了,就好办了。解决方法其实很简单,咱们只要让FragmentActivity被系统回收的时候,不保存Fragment的状态便可,即在FragmentActivity中重写onSaveInstanceState方法,而且注释掉super.onSaveInstanceState(outState)就好了。

1     @Override
2     protected void onSaveInstanceState(Bundle outState) {
3 //        super.onSaveInstanceState(outState);
4     }

 

总结:

  一、程序出现问题时,要先找出出现此问题的缘由,对症下药才能从根本上解决问题。

  二、对于Activity被系统回收致使的问题,可使用切换横竖屏来模拟场景。

 

最后感谢写http://my.oschina.net/u/1011854/blog/469138这篇帖子的朋友。

转载于:https://www.cnblogs.com/liuling/p/2015-9-21-1.html