Android View的状态保存
我们先看一个简单Demo,上代码。



当我们没有在布局控件Switch设置id时候,我们在竖屏页面打开开关,然后旋转屏幕,结果发现在横屏时候开关回到默认状态是关闭的,回到竖屏也还是关闭的,
通常来说,安卓会自动保存这些View的状态,但是在我们这个Demo中为啥就不起作用了呢?
后面发现跟我们这个控件没有这是id有关,没有设置id的话,我们去获取id会为-1。但当我们设置了id了,这个时候状态就可以正常保存了。
接下来我们从源码分析下。
首先当我们旋转屏幕时,会调用TestActivity的onSaveInstanceState()方法。从打印日志可以看出来。接着来分析Activity的onSaveInstanceState

这里主要做了这么几件事:
1 将mWindow.saveHierarchyState()中的数据,放入到Bundle对象中。
2 将Fragment的State数据存放到Bundle对象中。
3 将Bundle对象通过Application的dispatchActivitySaveInstanceState进行分发。
这里跟本篇涉及到的主要是:mWindow.saveHierarchyState()

这里重点接下来分析mContentParent.saveHierarchyState(states)



当如果设置了这个标志位时,一样是不能保存的。


View的onSaveInstanceState()是一个protected方法,供View的各个子类重写的。
看到这里基本上明白了,如果不给一个View设置一个id,那么Activity调用onSaveInstanceState(@NonNull Bundle outState)方法时,就没法保存它的状态,这会导致在需要取出Bundle状态对象时,出现现象不一致问题。