我們先看一個簡單Demo,上代碼。



當我們沒有在布局控件Switch設置id時候,我們在豎屏頁面打開開關,然后旋轉屏幕,結果發(fā)現(xiàn)在橫屏時候開關回到默認狀態(tài)是關閉的,回到豎屏也還是關閉的,
通常來說,安卓會自動保存這些View的狀態(tài),但是在我們這個Demo中為啥就不起作用了呢?
后面發(fā)現(xiàn)跟我們這個控件沒有這是id有關,沒有設置id的話,我們去獲取id會為-1。但當我們設置了id了,這個時候狀態(tài)就可以正常保存了。
接下來我們從源碼分析下。
首先當我們旋轉屏幕時,會調用TestActivity的onSaveInstanceState()方法。從打印日志可以看出來。接著來分析Activity的onSaveInstanceState

這里主要做了這么幾件事:
1 將mWindow.saveHierarchyState()中的數(shù)據(jù),放入到Bundle對象中。
2 將Fragment的State數(shù)據(jù)存放到Bundle對象中。
3 將Bundle對象通過Application的dispatchActivitySaveInstanceState進行分發(fā)。
這里跟本篇涉及到的主要是:mWindow.saveHierarchyState()?

這里重點接下來分析mContentParent.saveHierarchyState(states)



當如果設置了這個標志位時,一樣是不能保存的。


View的onSaveInstanceState()是一個protected方法,供View的各個子類重寫的。
看到這里基本上明白了,如果不給一個View設置一個id,那么Activity調用onSaveInstanceState(@NonNull Bundle outState)方法時,就沒法保存它的狀態(tài),這會導致在需要取出Bundle狀態(tài)對象時,出現(xiàn)現(xiàn)象不一致問題。