關於 Android 手機橫豎屏切換時 Activity 的生命周期問題,網上有很多相似的文章,大多數都是說明在豎屏切換橫屏時 Activity 會重啟一次,而在橫屏切換豎屏時 Activity 會重啟兩次。 我本身不太理解這樣設計的意義,並且覺得新版本會解決這個問題,所以做了一項測試,測試環境為 ...
關於 Android 手機橫豎屏切換時 Activity 的生命周期問題,網上有很多相似的文章,大多數都是說明在豎屏切換橫屏時 Activity 會重啟一次,而在橫屏切換豎屏時 Activity 會重啟兩次。
我本身不太理解這樣設計的意義,並且覺得新版本會解決這個問題,所以做了一項測試,測試環境為 Android 7.0 模擬器。
測試
測試首先創建一個新的 Activity,併在其各個生命周期方法內列印日誌,並執行如下操作得到結果:
在 targetSdkVersion 的值大於 12 時
Activity啟動
I/System.out: onCreate I/System.out: onStart I/System.out: onResume
豎屏切換為橫屏
I/System.out: onConfigurationChanged I/System.out: onPause I/System.out: onSaveInstanceState I/System.out: onStop I/System.out: onDestroy I/System.out: onCreate I/System.out: onStart I/System.out: onRestoreInstanceState I/System.out: onResume
橫屏切回豎屏
I/System.out: onConfigurationChanged I/System.out: onPause I/System.out: onSaveInstanceState I/System.out: onStop I/System.out: onDestroy I/System.out: onCreate I/System.out: onStart I/System.out: onRestoreInstanceState I/System.out: onResume
配置
android:configChanges="orientation|screenSize"
後,豎屏切換為橫屏I/System.out: onConfigurationChanged
配置
android:configChanges="orientation|screenSize"
後,橫屏切回豎屏I/System.out: onConfigurationChanged
在 targetSdkVersion 的值小於或等於 12 時
Activity啟動
I/System.out: onCreate I/System.out: onStart I/System.out: onResume
豎屏切換為橫屏
I/System.out: onConfigurationChanged I/System.out: onPause I/System.out: onSaveInstanceState I/System.out: onStop I/System.out: onDestroy I/System.out: onCreate I/System.out: onStart I/System.out: onRestoreInstanceState I/System.out: onResume
橫屏切回豎屏
I/System.out: onConfigurationChanged I/System.out: onPause I/System.out: onSaveInstanceState I/System.out: onStop I/System.out: onDestroy I/System.out: onCreate I/System.out: onStart I/System.out: onRestoreInstanceState I/System.out: onResume
配置
android:configChanges="orientation"
後,豎屏切換為橫屏I/System.out: onConfigurationChanged
配置
android:configChanges="orientation"
後,橫屏切回豎屏I/System.out: onConfigurationChanged
總結
可以發現新版本 Android 設備上的運行結果和網上的結論並不完全相同,在橫豎屏切換時,都會調用一次 onConfigurationChanged,並重啟 Activity 一次,行為完全一致,具體的生命周期為:
I/System.out: onConfigurationChanged
I/System.out: onPause
I/System.out: onSaveInstanceState
I/System.out: onStop
I/System.out: onDestroy
I/System.out: onCreate
I/System.out: onStart
I/System.out: onRestoreInstanceState
I/System.out: onResume
在 targetSdkVersion 的值大於 12 時,配置 android:configChanges="orientation|screenSize"
,
在 targetSdkVersion 的值小於或等於 12 時,配置 android:configChanges="orientation"
,
可以做到攔截 Activity 的重新創建:
I/System.out: onConfigurationChanged
後續
將會對過去版本的 Android 設備做相應的測試,來驗證得到結果。
改進
通常研究設備旋轉帶來的 Activity 重啟問題,是為瞭解決 Activity 重啟導致成員變數未保存引發運行出錯。但之所以 Activity 會重啟是因為運行時配置發生了更變,可能有更適合的資源來匹配新的設備配置,例如在橫屏時,有更好利用空間的橫版佈局資源,這時就需要 Activity 重新載入佈局顯示。
所以,好的解決辦法是利用 onSaveInstanceState(Bundle outState)
方法保存成員變數的值到 Bundle 對象中,在 Activity 重啟後,再在 onCreate(Bundle savedInstanceState)
中獲取這些保存的信息。