Activity 關於生命週期一些問題的實踐驗證
本文內容
1. 如何驗證問題
2. 正常狀況下的生命週期
3. 由活動 A 啓動活動 B 時,活動 A 的 onpause() 和 B 的 onResume() 哪個先執行?
4. dialog 是否會對生命週期產生影響?
4.1 標準的 AlertDialog 是否有影響?
4.2 全屏的 AlertDialog 是否有影響?
4.3 主題爲 Dialog 的 Activity 是否有影響?
5. 橫豎屏切換時生命週期變化
6. 內存不足殺死 Activity 時的生命週期變化
7. 異常狀況下數據保存
8. 異常狀況下,系統默認恢復 EditText 的文本信息
9. 異常狀況下,系統默認恢復 TextView 的文本信息
10. 防止重建
1. 如何驗證問題
建立一個 MainActivity 、 FirstActivity 類以及一些驗證問題的 Dialog 等等其餘的類,MainActivity 是項目的主界面。MainActivity 與 FirstActivity 的生命週期方法中都打印了日誌。
相關驗證代碼在:activityprojectandroid
2. 正常狀況下的生命週期
-
點擊應用到界面顯示出來的生命週期
結論:第一次打開 MainActivity ,調用了 onCreate() -> onStart() -> onResume() 方法。git
-
按下電源鍵時的屏保的生命週期
結論:屏保時的生命週期調用爲:onPause() -> onStop() 。github
-
亮屏時的生命週期
結論:亮屏時的生命週期調用爲:onRestore() -> onStart() -> onResume() 。web
-
按 home 鍵時的生命週期
結論:按下 home 鍵時的生命週期調用爲:onPause() -> onStop() 。shell
-
按 home 鍵後從新打開界面的生命週期(從後臺應用打開的生命週期是相同的)
結論:按下 home 鍵以後從新打開界面時的生命週期調用爲:onRestore() -> onStart() -> onResume() 。佈局
-
在顯示界面點擊返回鍵退出的生命週期
結論:關閉 MainActivity ,調用了 onPause() -> onStop() -> onDestory() 方法。測試
3. 由活動A啓動活動B時。活動A的 onPause() 與活動B的 onResume() 哪個先執行?
在 MainActivity 界面中添加一個按鈕,點擊按鈕跳轉 FirstActivity 界面。spa
- 打開 MainActivity 界面,在 MainActivity 跳轉到 FirstAcivity ,運行結果以下:
能夠看到,是 MainActivity 先執行了 onPause() , FirstActivity 的 onResume() 後執行的。3d
- 點擊返回看一下執行的順序:
點擊返回後,能夠看到是 FirstActivity 的 onPause() 先執行,MainActivity 的 onResume() 後執行。指針
結論:當活動 A 啓動活動 B 時,是活動 A 的 onPause() 方法先執行,活動 B 的 onResume() 方法後執行。
4.dialog 是否會對生命週期產生影響?
查看 Activity 生命週期的描述,若是 Activity 不在前臺,且並不是徹底不可見時, Activity 就會處在 onPause() 的暫停狀態。可是事實如何,用代碼說話,測試三種狀況:一,彈出標準的 AlertDialog ;二,彈出全屏的 AlertDialog ;三,彈出主題爲 Theme.AppCompat.Dialog 的 Activity ,查看這三種狀況下的生命週期的變化:
4.1 標準的 AlertDialog 是否有影響?
在 MainActivity 的佈局中添加一個彈出標準 AlertDialog 的按鈕,用於觀察 MainActivity 在彈出 AlertDialog 和隱藏 AlertDialog 的狀況下的生命週期變化。
-
點擊彈出標準 AlertDialog 的生命週期的運行
能夠看到彈出標準的 AlertDialog 並不會對 MainActivity 的生命週期有任何的影響。
-
點擊 AlertDialog 的「肯定」按鈕,對 AlertDialog 進行隱藏,觀察 MainActivity 的生命週期的變化
點擊 AlertDialog 的「肯定」按鈕後,看到沒有任何的日誌打印出來,全部隱藏標準 AlertDialog 也不會對 MainActivity 的生命週期有任何的影響。
結論:顯示和隱藏標準的 AlertDialog 不會對 MainActivity 的生命週期有任何的影響。
4.2 全屏的 AlertDialog 是否有影響?
在 MainActivity 的佈局中添加一個彈出全屏 AlertDialog 的按鈕,用於觀察 MainActivity 在彈出全屏 AlertDialog 和隱藏全屏 AlertDialog 的狀況下的生命週期變化。
-
點擊彈出全屏 AlertDialog 的生命週期的運行
能夠看到彈出全屏的 AlertDialog 並不會對 MainActivity 的生命週期有任何的影響。
-
點擊 AlertDialog 的「肯定」按鈕,對 AlertDialog 進行隱藏,觀察 MainActivity 的生命週期的變化
點擊 AlertDialog 的「肯定」按鈕後,看到沒有任何的日誌打印出來,全部隱藏全屏 AlertDialog 也不會對 MainActivity 的生命週期有任何的影響。
結論:顯示和隱藏全屏的 AlertDialog 不會對 MainActivity 的生命週期有任何的影響。
4.3 主題爲 Dialog 的 Activity 是否有影響?
在 MainActivity 的佈局中添加一個跳轉主題爲 Theme.AppCompat.Dialog 的 Activity 的按鈕,用於觀察 MainActivity 在跳轉主題爲 Theme.AppCompat.Dialog 的 Activity 和從 主題爲 Theme.AppCompat.Dialog 的 Activity 返回的狀況下的生命週期變化。
-
跳轉主題爲 Dialog 的 Activity 的生命週期變化
能夠看到跳轉主題爲 Dialog 的 Activity 會對 MainActivity 的生命週期產生影響,生命週期的變化與跳轉 Activity 的變化相同。
-
在主題爲 Dialog 的 Activity 下點擊返回鍵的生命週期變化
在主題爲 Dialog 的 Activity 下點擊返回鍵,返回到 MainActivity 的界面,從運行結果能夠看出,與跳轉 Activity 以後返回的聲明週期變化不一樣,MainActivity 只調用了 onResume() 方法,並無調用 onRestart() 與 onStart() 兩個方法,DialogActivity 調用 onPause()、onStop() 與 onDestory() 方法。
結論:主題爲 Dialog 的 Activity 會對 MainActivity 的生命週期有影響,而且跳轉主題爲 Dialog 的 Activity 與跳轉普通的 Activity 的生命週期變化相同。
5. 橫豎屏切換時生命週期變化
MainActivity 在橫豎屏切換時生命週期的變化:
結論:橫豎屏切換時的生命週期調用爲:onPause() -> onStop() -> onDestory() -> onCreate() -> onStart() -> onResume() 。就是一個銷燬再重建的過程。
內存不足殺死 Activity 時的生命週期變化
模擬內存不足殺死應用:先打開應用,而後按 home 鍵,使應用進入後臺,而後使用命令 adb shell am kill 包名
將應用殺死。
- 從打開應用到殺死應用的生命週期變化以下:
在按 home 鍵以後,MainActivty 調用了 onPause() 與 onStop() 方法,並無調用 onDestory() 方法,因此主進程如今屬於後臺進程。
結論:內存不足時,殺死應用,前臺的 Activity 生命週期爲 onPause() -> onStop() 。
- 而後在點擊應用的圖標,打開應用,生命週期變化以下:
能夠看到 MainActivity 調用了 onCreate()、onStart() 和 onResume() 方法,Activity 從新建立了。
7. 異常狀況下數據保存
在 MainActivity 中覆蓋 onSaveInstanceState 和 onRestoreInstanceState 兩個方法。在 onSaveInstanceState 方法中保存 key 值爲 message ,值爲 onSaveInstanceState 的數值,在 onRestoreInstanceState 方法中獲取 key 值爲 message 對應的數值,使用橫豎屏切換來測試這兩個方法的調用,以及保存數值的獲取。
-
從 MainActivity 開啓到切換橫豎屏的生命週期變化以下:
橫豎屏切換時,MainActivity 調用了 onSaveInstanceState() 方法,切換以後 MainActivity 從新建立,而且調用了 onRestoreInstanceState() 方法,並從 Bundle 中取得了 onSaveInstanceState() 方法中保存的數據。
-
再切換回來的生命週期變化以下:
切換回來與切換的時候的生命週期變化同樣,先調用了 onSaveInstanceState() 方法,切換後 MainActivity 從新建立並調用 onRestoreInstanceState() 方法,並從 Bundle 中取得了 onSaveInstanceState() 方法中保存的數據。
onCreate() 方法中也能獲取 onSaveInstanceState 方法中保存的數據,在 MainActivity 的 onCreate() 方法中增長獲取代碼。
- 橫豎屏切換以後 onCreate() 打印的日誌以下:
在 MainActivity 從新建立時,調用了 onCreate() 方法,並從 onCreate() 方法的 Bundle 中獲取到 onSaveInstanceState() 方法中存儲的值。注意:onCreate() 中從 Bundle 中獲取數據以前,必定要判空,由於第一次進入的時候,Bundle 是空的,會有空指針異常。
8. 在異常狀況下,系統默認恢復 EditText 的文本信息
在 MainActivity 的佈局文件中添加 EditText,打開應用後,在輸入框內輸入一些文字。在橫豎屏切換後觀察輸入框內的文字是否和切換以前的文字相同。(經過橫豎屏切換觀察信息,注意 EditText 須要添加 id 才行)
從打開應用,到橫豎屏切換以後輸入框的文字內容以下:
在切換橫豎屏時,onPause() 方法中打印了 EditText 的文本內容,切換重建後,在 onResume() 中獲取到 EditText 的內容與以前的內容相同,而且要注意,重建後 onCreate() 與 onStart() 方法中獲取 EditText 的文本內容都是爲空。
9. 在異常狀況下,系統默認恢復 TextView 的文本信息
經過轉屏觀察信息,這裏只是經過 setText 方法動態設置文本內容,在這種狀況下加了 id 也沒法自動保存,這種狀況能夠經過給 TextView 設置 freezesText 屬性才能自動保存。
打開應用後在點擊彈出標準的 AlertDialog 時修改 TextView 的內容,橫豎屏切換後,觀察 TextView 的內容是否和切換以前的文字相同。
從打開應用,到橫豎屏切換以後 TextView 的文字內容以下:
在切換橫豎屏時,onPause() 方法中打印了 TextView 的文本內容,切換重建後,在 onResume() 中獲取到 TextView 的內容與以前的內容相同,而且要注意,重建後 onCreate() 與 onStart() 方法中獲取 TextView 的文本內容是佈局文件中的默認內容。
10. 防止重建
將 MainActivity 的 android:configChanges 設置爲 orientation ,在橫豎屏切換的時候防止從新被建立。
- 橫豎屏切換時,生命週期的變化以下:
能夠看到在第一次進入 Activity 會調用 onCreate() -> onStart() -> onResume() 建立,以後切換橫豎屏並不會有任何的生命週期方法的調用。