一、 Activity生命周期的重要性
1.Activity棧:先進后出規則。每一個應用程序(入口一般會是一個Activity 的onCreate 方法),都會產生一個進程(Process)。當系統內存即將不足的時候,會依照優先級自動進行進程(process)的回收。不管是使用者或開發者, 都無法確定的應用程序何時會被回收。所以為了很好的防止數據丟失和其他問題,了解生命周期很重要。
二、Activity整個生命周期的4種狀態、7個重要方法和3個嵌套循環:
1.活動(Active/Running)狀態:當Activity運行在屏幕前臺(處于當前任務活動棧的最上面),此時它獲取了焦點能響應用戶的操作,屬于運行狀態,同一個時刻只會有一個Activity 處于活動(Active)或運行。
2.暫停(Paused)狀態:當Activity失去焦點但仍對用戶可見(如在它之上有另一個透明的Activity或Toast、AlertDialog等彈出窗口時)它處于暫停狀態。暫停的Activity仍然是存活狀態(它保留著所有的狀態和成員信息并保持和窗口管理器的連接),但是當系統內存極小時可以被系統殺掉。
3.非活動(Dead)狀態:Activity 尚未被啟動、已經被手動終止,或已經被系統回收時處于非活動的狀態,要手動終止Activity,可以在程序中調用"finish"方法。
4.7個重要的方法就不說了
5. 3個嵌套循環:1).Activity完整的生命周期:從第一次調用onCreate()開始直到調用onDestroy()結束;2).Activity的可視生命周期:從調用onStart()到相應的調用onStop()在這兩個方法之間,可以保持顯示Activity所需要的資源。如在onStart()中注冊一個廣播接收者監聽影響你的UI的改變,在onStop() 中注銷。3).Activity的前臺生命周期:從調用onResume()到相應的調用onPause()。
三、Dalvak 虛擬機會根據其內存回收規則來回收內存:(順序如下)
1. 先回收與其他Activity 或Service/Intent Receiver 無關的進程(即優先回收獨立的Activity)因此建議,我們的一些(耗時)后臺操作,最好是作成Service的形式
2.不可見(處于Stopped狀態的)Activity;
3.Service進程(除非真的沒有內存可用時會被銷毀);
4.非活動的可見的(Paused狀態的)Activity;
5.當前正在運行(Active/Running狀態的)Activity。
四、橫豎屏切換生命周期以及一些特殊情況聲明周期
例2:橫豎屏切換時候Activity的生命周期,他切換時具體的生命周期是怎么樣的:
1、新建一個Activity,并把各個生命周期打印出來。運行Activity,得到如下信息:
onCreate-->onStart-->onResume-->
2、按crtl+f12切換成橫屏時。onSaveInstanceState-->onPause-->onStop-->onDestroy-->
onCreate-->onStart-->onRestoreInstanceState-->onResume-->
3、再按crtl+f12切換成豎屏時,發現打印了兩次相同的log。
onSaveInstanceState-->onPause-->onStop-->onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume-->onSaveInstanceState-->onPause-->onStop-->onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume-->
4、修改AndroidManifest.xml,把該Activity添加android:configChanges="orientation",執行步驟3。onSaveInstanceState-->onPause-->onStop-->onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume-->
5、再執行步驟4,發現不會再打印相同信息,但多打印了一行onConfigChanged
onSaveInstanceState-->onPause-->onStop-->onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume-->onConfigurationChanged-->
6、把步驟5的android:configChanges="orientation" 改成 android:configChanges="orientation|keyboardHidden",執行步驟3,就只打印onConfigChanged,onConfigurationChanged-->
7、執行步驟4,打印onConfigurationChanged-->onConfigurationChanged-->
總結:
1)、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次
2)、設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次
3)、設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法
4)、補充一點,當前Activity產生事件彈出Toast和AlertDialog的時候Activity的生命周期不會有改變
5)、Activity運行時按下HOME鍵(跟被完全覆蓋是一樣的):onSaveInstanceState --> onPause --> onStop,再次進入激活狀態時:?onRestart -->onStart--->onResume
五、 Activity四種啟動方式和棧原理
1. standard:模式啟動模式,每次激活Activity時都會創建Activity,并放入任務棧中。
2.?singleTop:如果在任務的棧頂正好存在該Activity的實例,?就重用該實例,否者就會創建新的實例并放入棧頂(即使棧中已經存在該Activity實例,只要不在棧頂,都會創建實例)。
3.?singleTask:如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的onNewIntent())。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移除棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
4.?singleInstance:在一個新棧中創建該Activity實例,并讓多個應用共享改棧中的該Activity實例。一旦改模式的Activity的實例存在于某個棧中,任何應用再激活改Activity時都會重用該棧中的實例,其效果相當于多個應用程序共享一個應用,不管誰激活該Activity都會進入同一個應用中。
備注: 后續有深入的理解,一定繼續補充.....