這篇文章大部份內容來自Activity的全方面解析,本文只是往加上Activity的全方面解析這篇文章沒法 顯示的圖片和一些沒有介紹的部分基礎內容html
如圖所示,在正常狀況下,一個Activity從啓動到結束會以以下順序經歷整個生命週期:android
onCreate():當 Activity 第一次建立時會被調用。這是生命週期的第一個方法。在這個方法中,能夠作一些初始化工做,好比調用setContentView去加載界面佈局資源,初始化Activity所需的數據。git
onRestart():表示Activity正在從新啓動。通常狀況下,當前Activity從不可見從新變爲可見狀態時,onRestart就會被調用。這種情形通常是用戶行爲致使的,好比用戶按Home鍵切換到桌面或打開了另外一個新的Activity,接着用戶又回到了這個Actvity。ide
onStart(): 表示Activity正在被啓動,即將開始,這時Activity已經出現了,可是尚未出如今前臺,沒法與用戶交互。這個時候能夠理解爲Activity已經顯示出來,可是咱們還看不到。佈局
onResume():表示Activity已經可見了,而且出如今前臺並開始活動。須要和onStart()對比,onStart的時候Activity還在後臺,onResume的時候Activity才顯示到前臺。ui
onPause():表示 Activity正在中止,仍可見,正常狀況下,緊接着onStop就會被調用。在特殊狀況下,若是這個時候快速地回到當前Activity,那麼onResume就會被調用(極端狀況)。onPause中不能進行耗時操做,會影響到新Activity的顯示。由於onPause必須執行完,新的Activity的onResume纔會執行。spa
onStop():表示Activity即將中止,不可見,位於後臺。能夠作稍微重量級的回收工做,一樣不能太耗時。code
onDestory():表示Activity即將銷燬,這是Activity生命週期的最後一個回調,能夠作一些回收工做和最終的資源回收cdn
當咱們看新聞時,出現電話、信息等通知,此時activity
不會調用生命週期的方法,只有你點擊通知跳轉到其餘activity
時,纔會調用onPause
->onStop
方法xml
當咱們按Home
鍵切換到桌面後又回到該Actitivy
,回調以下:onPause()
->onStop()
->onRestart()
->onStart()
->onResume()
當咱們按back鍵回退時,回調以下:onPause()
->onStop()
->onDestory()
在生命週期方法中調用finish()
時,activity
的生命週期與調用finish()
的位置有關(調用完finish()
後,不會直接退出該生命週期的方法,而是先執行完所在的生命週期方法):
onCreate()
中調用時,先執行完onCreate()
,回調爲onDestory()
onStart()
中調用時,回調爲:onStop()
->onDestory()
onResume()
中執行時,回調爲:onPause()
->onStop()
->onDestory()
onPause()
中執行時,回調爲:onStop()
->onDestory()
onStop()
中調用時,回調爲:onDestory()
橫豎屏切換的生命週期回調爲:onPause()
->onSaveInstanceState()
-> onStop()
->onDestroy()
->onCreate()
->onStart()
->onRestoreInstanceState
->onResume()
onSaveInstanceState()
用來在橫豎屏切換時保存當前activity
的狀態,當activity
重建時,系統會而且把Activity
銷燬時onSaveInstanceState
方法所保存的Bundle
對象參數同時傳遞給onRestoreInstanceState
和onCreate
方法.(onCreate
和onRestoreInstanceState
的區別就是onCreate傳遞過來的Bundle
對象可能爲null,而onRestoreInstanceState
的不會爲null)
在AndroidManifest.xml
的activity
中禁用橫豎屏切換
android:configChanges = "orientation| screenSize"
複製代碼
此時,不會進行橫豎屏切換,而是調用onConfigurationChanged(Configuration newConfig)
方法。
Activity
的優先級從高到低,可分爲以下三種:
Activity
: 正在和用戶交互的Activity
Activity
:好比Activity中彈出了一個對話框,致使Activity可見可是位於後臺沒法和用戶交互當系統內存不足時,會按照上述優先級從低到高去殺死目標Activity所在的進程。
Activity的管理是採用任務棧的形式,任務棧採用「後進先出」的棧結構。
Android
的任務棧由TaskAffinity
指定,TaskAffinity
標識了一個Activity
所須要的任務棧的名字。默認狀況下TaskAffinity
爲包名。通常咱們不改變TaskAffinity
的默認值,不一樣的應用屬於不一樣的任務棧,同一個應用都在同一個任務棧。咱們能夠經過設置TaskAffinity
來讓同一應用中的不一樣的Activity
屬於不一樣的任務棧。
前臺任務棧和後臺任務棧的區別:前臺任務棧和後臺任務棧都是任務棧,不一樣的是前臺任務棧中存在Activity
與爲用戶所見,然後臺的任務棧中的Activity
都在後臺
Android提供了四種Activity啓動方式:
每啓動一次Activity
,就會建立一個新的Activity
實例並置於棧頂。誰啓動了這個Activity
,那麼這個Activity
就運行在啓動它的那個Activity
所在的棧中。
特殊狀況:
假設有應用A和應用B,A啓動另外一個應用B的MainActivity
(入口Activity)時,會建立一個新的任務棧,並將另外一個應用的Activity
置於這個新棧中。若是啓動另外一個應用的非入口Activity
(此時這個被啓動Activity
要求android:exported
屬性爲true),則會將這個應用B的Activity
放在應用A的棧中
若是在Service或Application中啓動一個Activity,其並無所謂的任務棧,能夠爲待啓動的Activity指定FLAG_ACTIVITY_NEW_TASK
標記位,建立一個新棧。
注意在5.0以前A啓動另外一個應用B的
MainActivity
(入口Activity)時,新啓動的Activity
實例會放入發送Intent的Task的棧的頂部,儘管它們屬於不一樣的程序
若是須要新建的Activity位於任務棧棧頂,那麼此Activity的實例就不會重建,而是重用棧頂的實例,此時會調用Activity
的onNewIntent(Intent intent)
方法。若是棧頂不是新建的Activity,就會建立該Activity新的實例,並放入棧頂。
注意:在Android 5.0以前,若是是外部程序啓動singleTop的Activity,新建立的Activity會位於調用者的Task中,5.0及之後會放入新的Task中。
該模式是一種單例模式,即一個棧內只有一個該Activity
實例。該模式,能夠經過在AndroidManifest.xml
文件的taskAffinity
屬性指定該Activity
須要加載到那個棧中。若是Activity
指定的棧不存在,則建立一個棧,並把建立的Activity
壓入棧內。若是Activity
指定的棧存在,若是其中沒有該Activity
實例,則會建立Activity
並壓入棧頂,若是其中有該Activity實例,則把該Activity
實例之上的其餘Activity
殺死清除出棧,重用並讓該Activity
實例處在棧頂,而後調用onNewIntent()
方法。
做爲棧內複用模式(singleTask)的增強版,打開該Activity時,直接建立一個新的任務棧,並建立該Activity實例放入新棧中。一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例。
Activity
假如目前有兩個任務棧。前臺任務棧爲AB,後臺任務棧爲CD,這裏假設CD的啓動模式均爲singleTask,如今請求啓動D,那麼這個後臺的任務棧都會被切換到前臺,這個時候整個後退列表就變成了ABCD。當用戶按back返回時,列表中的activity會一一出棧,
若是不是請求啓動D而是啓動C,那麼狀況又不同,這個時候整個後退列表就變成了ABC
Activity的Flags不少,這裏介紹集中經常使用的,用於設定Activity的啓動模式。能夠在啓動Activity時,經過Intent的addFlags()方法設置。