java.lang.IlleagalStateException解决方法简记

java.lang.IlleagalStateException解决方法简记_第1张图片

  1. 背景

          Monkey测试时报出异常java.lang.IlleagalStateException,异常抛出位置位于android.app.FragmentManagerImpl,FragmentManagerImpl在FragmentManager内定义,并且是FragmentManagerImpl的子类。

          FragmentManagerImpl与Activity关联,负责管理这个Activity所拥有的Fragment,使Activity的声明周期发生改变时,同步调用与该Activity相关联的Fragment的对应生命周期方法。

          java.lang.IlleagalStateException解决方法简记_第2张图片

         该异常由checkStateLoss方法抛出,可以看出当mStateSaved状态为true,即抛出该异常,并且由异常提醒可以看出,抛出该异常的原因是在onSavedInstaceState方法执行后又执行了某种操作。

         由初始的问题日志堆栈可以看出,抛出该异常时,正在执行的操作是removeHistoryFragment,即移除Activity中的某一个Fragment,查看Activity的onSavedInstance文档没有特别的提示,那么查看相关源码:

 java.lang.IlleagalStateException解决方法简记_第3张图片

           在onSavedInstanceState中,红框框出的代码,调用了mFragments.saveAllSate方法,仅仅通过查看方法名也可以猜测出该方法用于保存Fragment的状态,以便于Activity还原时,同步还原Fragment。该方法中将mStateSaved置为true。

         因此可以初步总结,一旦onSavedInstance方法被执行,Activity中Fragment的状态也同步被保存,此时相关代码逻辑将不允许再对该Activity执行Fragment的添加/移除等操作。

         实际上,Activity的onSavedInstance一旦被执行,将不再允许对Activity执行会改变Activity状态的操作,一旦这类操作出现,就会触发java.lang.IlleagalStateException。

     2. 总结

       onSavedInstance方法用于保存Activity当前的状态,以便当重新切换回该Activity时恢复其状态,根据Android Doc,该方法会在Activity可能会被回收时执行,这种情况通常出现在Android内存紧张,且当前Activity不处于Resumed状态时,因此一般情况下不会由于用户的操作导致该异常抛出,但是神奇的Monkey测出了这种异常。。。

    3.解决方法

      仅针对这个问题而言,可以使用下列两种方法解决。

     3.1   Activity重写onSavedInstance方法,不调用super.onSavedInstance,这样自然不会导致mStateSaved状态的设置,但是Fragment中的状态无法保存,必须手动去实现,并且不执行父类实现可能会导致某些未知的副作用,不推荐。

     3.2  使用反射获取FragmentManagerImpl中的mSaveState,在异常抛出位置检测mSavedState参数,从而规避异常检查。

java.lang.IlleagalStateException解决方法简记_第4张图片

java.lang.IlleagalStateException解决方法简记_第5张图片

你可能感兴趣的:(个人笔记,问题总结)