onSaveInstanceState是干什么的呢?
通过该方法保留的实例状态数据,然后借助onCreate(Bundle) or onRestoreInstanceState(Bundle),我们可以将已被killed的activity恢复回来。用户界面状态能够通过onCreate(Bundle) or onRestoreInstanceState(Bundle)来恢复,
onSaveInstanceState一定会被调用,NO:
1.用户主动从B页面回退到A页面,B页面从栈中弹出,用户不会再回退到B页面,所以也不用去保存数据来恢复B
2.B页面展示在A页面上,如果A在B的生命周期内绝对不被销毁
onSaveInstanceState到底存了什么数据?
保存了继承体系中每个view(带id的)大部分实例状态 ,并且存储当前热点view的id.它默认只保存了一些UI view的状态信息,可以通过覆写该方法来存储一些想要保存的额外数据。
做了一个简单的demo,
当屏幕旋转的时候,发生activity的重建。通过查看bundle来看,系统收集了这些内容,
Bundle[
{
android:views=
{
16908290=android.view.AbsSavedState$1@59774b2,
2131492954=android.view.AbsSavedState$1@59774b2,
2131492955=android.view.AbsSavedState$1@59774b2,
2131492956=android.support.v7.widget.Toolbar$SavedState@ab71c03,
2131492957=android.view.AbsSavedState$1@59774b2,
2131493008=TextView.SavedState{7d20780 start=7 end=7 text=fghhfgg
}
},
android:focusedViewId=2131493008}]
2131493008=TextView.SavedState{7d20780 start=7 end=7 text=fghhfgg}
关于TextView有其当前输入的内容fghhfgg,key是该TextView的id,
android:focusedViewId=2131493008
接着保存当前焦点停留的view的id号,刚好就是上面的textView.
注:没有id的view是不会为其保存状态信息的
从设计上来看为什么要禁止onSaveInstanceState之后执行某种action
对于应用来说,他对自己的生杀大权并不是完全掌握,很容易因为内存紧张而被杀死,但是android系统并不希望这样带给用户一种不一致甚至突兀的感觉。
onSaveInstanceState的时机是?
If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().
根据官方的定义,onSaveInstanceState 会在onStop前调用,但是不保证是在onPause之前还是之后被调用。
当我按下home健的时候
可以看的出,onSaveInstanceState在页面回到后台的操作执行后会很快被调用的。几乎在页面还未完全消失之前就调用了。
异常产生的关键判断条件:mStateSaved
当Fm中的mStateSaved为true的时候,进行fragment相关操作的时候会产生异常。
mStateSaved被修改为true 的场景是:
onStop调用时
onSaveInstanceState 调用时
mStateSaved被修改为false的场景是:
onCreate
onActivityCreated
onStart
onResume
需要注意哪些地方呢?
不要在异步方法中操作fragment
异步方法的回调时机很可能会出现在onSaveInstanceState调用后。
谨慎使用onBackPressed()替换finish()
在onBackPressed间接的会去调用checkStateLoss()
不要在onActivityResult中操作fragment
在onStart中fm才将mStateSaved修改为false,在这之前任何的fragment操作必然导致state loss.
DialogFragment的show()操作
有人说覆写show,然后替换为commitAllowStateLoss,ok。但是回到“从设计上来看为什么要禁止onSaveInstanceState之后执行某种action”来看,如果crash非常少量,那我们给用户带来突兀感觉的代价几乎可以忽略不及,catch住这个异常未尝不可。