思考:
看到這個題目相信很多人有這種感覺,太簡單了碗暗,如果讓他描述每個生命周期名字作用,啟動過程梢夯,從第一個頁面跳到第二個頁面生命周期的過程言疗。不一定說的清楚,所以記錄下來加深一下印象颂砸。
1.activity的生命周期
先貼一張官方文檔(http://developer.android.com/reference/android/app/Activity.html)的圖噪奄。
相信這張圖你百分百看過,我來簡略的介紹一下Activity的生命周期:
上面圖片截的不好看人乓,有好的滾動截圖工具可以推薦一下勤篮。
1. 給每個生命周期寫上日志,啟動app色罚,可以看到啟動一個activity的生命周期碰缔,如下圖:
2.同樣你再新建一個頁面,從第一個頁面跳轉到第二個頁面到生命周期保屯,如下圖:大家可以看到手负,跳轉時,第一個頁面先onPause,當前看到的還是第一頁面姑尺,等到第二個頁面啟動成功了竟终,才看到第二頁面,并停止第一頁面切蟋。
3.還有一個自調用的方法onSaveInstanceState:
當我們的app長時間切到后臺统捶,或者一些不在棧頂?shù)捻撁妫斘覀冎匦逻M入的時候,這個Activity或者Fragment就會被重新onCreate喘鸟,但是此時匆绣,頁面中具有id的控件,這些值都是會被系統(tǒng)自動保存下來的什黑。這是因為onSaveInstanceState()這個方法起了作用崎淳。
4.橫豎屏切換的時候,生命周期方法的回調順序為:
onPause--onSaveInstanceState--onStop--onDestory--onCreate--onStart--onResume
也就是說Activity被銷毀并重建了愕把。當然你也可以在清單文件中對應的Activity添加一行配置:
android:configChanges="keyboardHidden|orientation|screenSize"
2.activity的啟動模式
什么是Task
Task拣凹,簡單的說,就是一組以棧的模式聚集在一起的Activity組件集合恨豁。它們有潛在的前后驅關聯(lián)嚣镜,新加入的Activity組件,位于棧頂橘蜜,并僅有在棧頂?shù)腁ctivity菊匿,才會有機會與用戶進行交互。而當棧頂?shù)?Activity完成使命退出的時候计福,Task會將其退棧跌捆,并讓下一個將跑到棧頂?shù)腁ctivity來于用戶面對面,直至棧中再無更多 Activity棒搜,Task結束疹蛉。
task是一系列activity的集合,?這些activity通常因為同一目的而啟動,?系統(tǒng)將這些activity按照創(chuàng)建的順序組織在棧中(也就是所謂的back stack).?每一個task都擁有一個僅屬于它的back stack.
管理任務和回退棧
1.通過Activity的啟動模式去控制:Activity的?launchMode
? ?standard:?(備注:standard是系統(tǒng)默認的啟動模式活箕。)
????????標準啟動模式力麸,每次激活Activity時都會創(chuàng)建Activity,并放入任務棧中育韩。
如果啟動此Activity的Intent中沒有設置FLAG_ACTIVITY_NEW_TASK標志, 則這個Activity與啟動他的Activity在同一個Task中,如果設置了Activity請參考上面FLAG_ACTIVITY_NEW_TASK的詳細說明,"launchMode"設置為"standard"的Activity可以?被實例化多次, 可以在Task中的任何位置, 對于一個新的Intent請求就會實例化一次.
? ?singleTop:?
????????如果在任務的棧頂正好存在該Activity的實例克蚂, 就重用該實例,而不會創(chuàng)建新的Activity對象筋讨,不過它會調用?onNewIntent()方法埃叭。如果棧頂部不存在就會創(chuàng)建新的實例并放入棧頂(即使棧中已經存在該Activity實例,只要不在棧頂悉罕,都會創(chuàng)建實例)赤屋。
????????如果啟動此Activity的Intent中沒有設置FLAG_ACTIVITY_NEW_TASK標志, 則這個Activity與啟動他的Activity在同一個Task中,如果設置了Activity請參考上面FLAG_ACTIVITY_NEW_TASK的詳細說明,"launchMode"設置為"singleTop"的Activity?可以被實例化多次, ?可以在Task中的任何位置, 對于一個新的Intent請求如果在Task?棧頂, 則會用棧頂?shù)腁ctivity響影Intent請求,而?不會重新實例化對象接收請求, 如果?沒有在棧頂, 則會?實例化一個新的對象接收Intent請求.
? singleTask:?
????????如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的?onNewIntent())壁袄。重用時类早,會讓該實例回到棧頂,因此在它上面的實例將會被移除棧嗜逻。如果棧中不存在該實例涩僻,將會創(chuàng)建新的實例放入棧中。?
????????和singleTop在名字上即可看出區(qū)別,即singleTop每次只檢測當前棧頂?shù)腁ctivity是否是我們需要請求創(chuàng)建的逆日,而singleTask則會檢測棧中全部的Activity對象嵌巷,從上向下,如果檢測到是我們所請求的則會消滅此Activity對象上面的對象室抽,直接把檢測到的我們需要的Activity置為棧頂搪哪。
? ? ? ? "launchMode"設置為"singleTask"的Activity?總是在棧底,?只能被?實例化一次, 它允許其它Activity壓入"singleTask"的Activity所在的Task棧,如果有新的Intent請求有此標志的Activity, 則系統(tǒng)會清除有此標志的Task棧中的全部Activity,并把此Activity顯示出來.
? singleInstance:?
????????在一個?新棧中創(chuàng)建該Activity實例,并讓多個應用共享該Activity實例坪圾。一旦這種模式的Activity實例存在于某個棧中噩死,任何應用再激活這個Activity時都會重用該棧中的實例,其效果相當于多個應用程序共享一個應用神年,不管誰激活該Activity都會進入同一個應用中已维。此啟動模式和我們使用的瀏覽器工作原理類似,在多個程序中訪問瀏覽器時已日,如果當前瀏覽器沒有打開垛耳,則打開瀏覽器,否則會在當前打開的瀏覽器中訪問飘千。此模式會節(jié)省大量的系統(tǒng)資源堂鲜,因為他能保證要請求的Activity對象在當前的棧中只存在一個。
? ? ? ? ?"launchMode"設置為"singleInstance"的Activity總是在棧底, 只能被實例化一次, 不允許其它的Activity壓入"singleInstance"的Activity所在Task棧, ?即?整個Task棧中只能有這么一個Activity.
設置啟動模式的位置在?AndroidManifest.xml 文件中 Activity 元素的?android:launchMode 屬性
2.動態(tài)的啟動模式:在new 一個Intent后护奈,通過Intent的addFlags方法去動態(tài)指定一個啟動模式
Intent intent = new Intent();intent.setClass(context,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
以下介紹幾個基本的標記位缔莲,不用背,須要時再查官方文檔:
1. FLAG_ACTIVITY_NEW_TASK
作用是為Activity指定 “SingleTask”啟動模式霉旗。跟在AndroidMainfest.xml指定效果同樣痴奏。
2. FLAG_ACTIVITY_SINGLE_TOP
作用是為Activity指定 “SingleTop”啟動模式,跟在AndroidMainfest.xml指定效果同樣厌秒。
3. FLAG_ACTIVITY_CLEAN_TOP
具有此標記位的Activity读拆,啟動時會將與該Activity在同一任務棧的其他Activity出棧。一般與SingleTask啟動模式一起出現(xiàn)鸵闪。它會完畢SingleTask的作用檐晕。但事實上SingleTask啟動模式默認具有此標記位的作用
4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有此標記位的Activity不會出如今歷史Activity的列表中,使用場景:當某些情況下我們不希望用戶通過歷史列表回到Activity時蚌讼,此標記位便體現(xiàn)了它的效果辟灰。它等同于在xml中指定Activity的屬性:
結束語:
關于Activity 的生命周期和啟動模式,有很多值得我們不斷研究的知識篡石,我僅僅只是拋磚引玉芥喇。大家一定要自己動手去嘗試。
GitHub:https://github.com/DaveSally/MyDemo
歡迎大家關注我的公眾號:受傷的粽子