问题引入
在项目某个Activity中使用viewPage下嵌套了3个fragment A,B,C。A页面保存一些需要联网获取但是在每次使用过程中不会改变的信息。 测试软件时发现每次打开c fragment后再点开a fragment a中的view需要重新联网获取数据。
问题分析
查询资料可知viewpage会缓存当前fragment左边和右边总共3个页面,当我打开c fragment时候,viepage主动杀死 a页面
解决方案一
立刻想到,重写fragment的onSaveInstanceState() 和onCreateView() ,在fragment被销毁是将view 的数据存起来,在重新打开页面时候自动填写.
结果:失败!
给方法打上log,运行app

观察发现在打开fragment c 时候 并没有调用 fragment a 的onSaveInstanceState()而是直接调用了 ondestroyview(),
原因是系统在调用onPause 和 onStop时候并不是每次都会调用onSaveInstanceState,只有系统自动回收资源的时候觉得该 Activit 在将来某个时刻重新回来时可以恢复其之前的状态。例如,如果 Activity B 启用后位于 Activity A 的前端,在某个时刻 Activity A 因为系统回收资源的原因要被销毁,Activity A 有机会通过 onSaveInstanceState() 来保存其用户界面状态,使得将来用户返回到 Activity A 的时候能够通过onCreate(Bundle) 或者onRestoreInstanceState(Bundle) 来恢复其界面状态。而viewPage直接调用了fragment 的 ondestroyview。而并没有调用ondeatch所以fragment是还存的,只是里面的view 被摧毁了,所以下次点开fragment a 需要重新获取数据.
解决方案二
因为infoactivity 和 fragment a 其实是一直存活的没有被杀死 所以我们不能通过他们的生命周期毁回调函数来实现自动填充view这个功能,难道我们就束手无策了嘛?
显然不是,其实view是有自己的生命周期的,view 也有自己的onSaveI nstanceState 和 onRestoreInstanceState函数,我们只要在view中重写这两个函数就可以实现以上功能
而且更加好的消息是基本上,每个标准视图(例如EditText,TextView,Checkbox等)都已经在内部实现了这些功能,你只需要将其设置android:freezeText为true。
但是某些自定义的view未必实现这个功能,到时候就需要我们自己重写了.
总结
用onSaveI nstanceState 和 onRestoreInstanceState函数是非常好的用来保护和自动填充内容的方式,但是一定要分清楚avitvity ,fragment ,和view各自的生命周期,如果任何属性属于View,请在View内部进行状态保存/还原,不要将view 的属性放在fragment 的生命周期中操作