Activity的基礎(chǔ)知識(啟動模式旧蛾、生命周期等)

在Android里,一個Activity一般是用于負(fù)責(zé)創(chuàng)建一個頁面,通過setContentView(View)方法向用戶展示你的UI瀑粥。

若想啟動一個Activity豆挽,可以通過Context.startActivity(Intent)炫七,并且這個Activity要在AndroidManifest.xml清單文件里進(jìn)行申明磕蛇。有時你想從Activity結(jié)束時得到結(jié)果;例如囱桨,你可以啟動一個Activity仓犬,讓用戶在聯(lián)系人列表中選擇一個人; 當(dāng)它結(jié)束時,它返回選擇的人舍肠。為此搀继,你可以通過調(diào)用Activity.startActivityForResult(Intent, int),使用第二個整型的參數(shù)標(biāo)識你的請求翠语,然后在Activity的onActivityResult(int, int, Intent)方法會返回你請求的結(jié)果律歼。

啟動模式

在同一個時間段只能有一個Activity是運(yùn)行的(其他Activity就算可見也不能獲得焦點(diǎn),觸摸事件等)啡专,多個Activity是由Activity堆棧管理的,當(dāng)啟動了一個新的Activity制圈,它就會被放置在這個棧的頂部们童,上一個Activity總是保持在棧的下面,也就是在這個新的Activity后面鲸鹦,直到新的Activity退出慧库。但是一個應(yīng)用程序里面棧不一定是只有一個的,這個由Activity的啟動模式?jīng)Q定的:

  • standard:不管棧里有沒有已存在的實例馋嗜,都會在當(dāng)前棧中生成新的實例齐板;
  • singleTask:如果當(dāng)前棧存在重復(fù)的Activity,則把重復(fù)的Activity置頂葛菇,在這個Activity之上的其他實例都會被移出棧甘磨;
  • singleInstance:跟其他Activity不在一個棧中,獨(dú)立一個棧眯停,并且這個棧只能擁有這一個Activity济舆,并且如果以存在這個實例時,會重用這個實例;
  • singleTop:如果當(dāng)前棧頂?shù)腁ctivity是重復(fù)的莺债,則可以重復(fù)利用滋觉,否則生成新的實例签夭;

申明Activity的啟動模式是在AndroidManifest.xml清單文件里進(jìn)行的,通過android:launchMode="singleTask"這樣的形式申明椎侠,一般App的首頁Activity都會申明為singleTask第租。

生命周期

一個Activity通常有4種狀態(tài):

  • 如果一個Activity在屏幕的前臺里顯示(在Activity棧的頂部),它是運(yùn)行的狀態(tài)(active or running)我纪。
  • 如果一個Activity失去了焦點(diǎn)但是仍然保持可見狀態(tài)(例如一個不是填滿屏幕或者是透明的Activity在這個Activity的上面慎宾,很多App把Activity主題設(shè)置為透明的可滑動退出就屬于這種),它是處于暫停的狀態(tài)(paused)宣羊。一個暫停的Activity仍然是存活的(它保持所有狀態(tài)和成員信息璧诵,并保持附加到窗口管理器),但在內(nèi)存非常緊張不足的時候可能會被殺死仇冯。
  • 如果一個Activity完全被另外一個Activity遮擋住之宿,它是處于停止的狀態(tài)(stopped)。它仍然保留所有的狀態(tài)和成員信息苛坚,但是比被,它不再是用戶可見的,所以它的窗口被隱藏泼舱,當(dāng)需要內(nèi)存時等缀,它經(jīng)常會優(yōu)先被殺死。
  • 如果一個Activity是處于暫徒筷迹或者停止的狀態(tài)尺迂,則系統(tǒng)可以通過請求它完成或者簡單地殺死它的進(jìn)程來從內(nèi)存中刪除該Activity。當(dāng)它需要再一次顯示給用戶的時候冒掌,必須完全重新啟動(restarted)和恢復(fù)(restored)它之前的狀態(tài)噪裕。
    為了避免內(nèi)存不足把托管Activity的進(jìn)程殺死時數(shù)據(jù)丟失,一般情況下都會在onPause()方法里面進(jìn)行數(shù)據(jù)的持久化存儲股毫。此外膳音,onSaveInstanceState(Bundle)方法也會被調(diào)用,你可以將Activity的任何動態(tài)實例狀態(tài)(例如當(dāng)前頁面滑動的位置铃诬,顯示的內(nèi)容)保存到給定的Bundle中祭陷,然后當(dāng)Activity需要顯示時,會在它的onCreate(Bundle)方法里接收到這個Bundle趣席。

下圖是Activity主要的生命周期兵志,長方形表示你可以在Activity的狀態(tài)切換時實現(xiàn)的回調(diào)方法,彩色橢圓形是Activity可以處于的主要狀態(tài)宣肚。

activity_lifecycle.png

你可能有興趣在你的Activity中監(jiān)控的三個關(guān)鍵循環(huán):

  • 在 Activity的整個生命周期里毒姨,第一次調(diào)用onCreate()到最后調(diào)用onDestroy()的時候。一般在onCreate()進(jìn)行一些初始化操作钉寝,通過findViewById()進(jìn)行View的初始化弧呐,在onDestroy()里進(jìn)行資源的釋放闸迷。例如,如果在onCreate()里開啟線程俘枫,從網(wǎng)絡(luò)下載相應(yīng)的數(shù)據(jù)腥沽,然后再onDestroy()里停止線程。
  • Activity的可見生命周期是從調(diào)用onStart()到調(diào)用onStop()鸠蚪,在此期間今阳,用戶可以在屏幕上看到該Activity,雖然它可能不在前臺與用戶交互茅信。在這兩個方法之間盾舌,您可以維護(hù)向用戶顯示Activity所需要的資源。例如蘸鲸,通過BroadcastReceiveronStart()注冊廣播監(jiān)聽器妖谴,更新你的UI,當(dāng)用戶不再看到你顯示的內(nèi)容時在onStop()里取消該監(jiān)聽事件酌摇。
  • Activity的前臺生命周期是從調(diào)用onResume()到調(diào)用onPause()膝舅,在此期間,Activity在所有其他的Activity前面窑多,并與用戶交互仍稀。例如,當(dāng)設(shè)備進(jìn)入休眠時埂息,Activity結(jié)果被傳遞時技潘,當(dāng)一個新的意圖(Intent)發(fā)起時,所以在這方法中的代碼應(yīng)該是比較輕量級的千康,不會阻塞UI享幽。

值得一提的是,很多App在界面上是可滑動退出的吧秕,如果Activity是透明的,那么在這個Activity啟動時迹炼,前一個Activity會調(diào)用onPause()砸彬,但不會調(diào)用onStop()方法,應(yīng)為前一個Activity仍然屬于可見狀態(tài)斯入,盡管是完全被遮住看不見而已砂碉,當(dāng)這個Activity退出后,前一個Activity只會調(diào)用onResume()方法刻两,而不會執(zhí)行onRestart()onStart()方法增蹭;還有很多時候,你若想要通過廣播等方法去監(jiān)聽某些事件磅摹,然后更新UI滋迈,如果你要一直保持更新UI盡管已經(jīng)啟動了新的Activity在前面霎奢,這個時候就不能再onStart()onStop()方法對里去注冊取消監(jiān)聽了,而是應(yīng)該在onCreate()onDestroy()里進(jìn)行饼灿;

配置更改

如果設(shè)備的配置(由Resources.Configuration類定義 )更改幕侠,則顯示用戶界面的任何內(nèi)容都需要更新以匹配該配置。因為Activity是與用戶交互的主要機(jī)制碍彭,所以它包括用于處理配置更改的特殊支持晤硕。

除非你指定,配置變更(如屏幕方向庇忌,語言舞箍,輸入設(shè)備等的變化)會導(dǎo)致你的當(dāng)前Activity被破壞,通過正常的Activity生命周期過程適當(dāng)?shù)貓?zhí)行onPause()皆疹, onStop()onDestroy()疏橄。如果活動已經(jīng)在前臺或用戶可見,一旦onDestroy()在該實例中被調(diào)用墙基,那么將創(chuàng)建新的Activity實例软族,而前一實例通過onSaveInstanceState(Bundle)保存數(shù)據(jù)到Bundle里,再通過onCreate(Bundle)Bundle恢復(fù)之前的數(shù)據(jù)残制。

在某些特殊情況下立砸,你可能希望根據(jù)一種或多種類型的配置更改繞過重新啟動Activity,這時可以通過在AndroidManifest.xml清單文件里申明Activity時初茶,申明android:configChanges屬性來完成颗祝。對于您處理的任何類型的配置更改,您將收到對當(dāng)前ActivityonConfigurationChanged(Configuration)方法的調(diào)用恼布, 而不是重新啟動螺戳。如果配置更改涉及到你不處理的配置更改,則Activity仍將重新啟動折汞,onConfigurationChanged(Configuration)也不會被調(diào)用倔幼。

有些時候,你的Activity是支持橫豎屏切換的(例如看視頻)爽待,本身界面也是支持橫豎屏的切換顯示损同,為了避免重新啟動Activity,可以這樣android:configChanges="screenSize|orientation|keyboardHidden"鸟款,screenSize|orientation是屏幕的變化時會更改的屬性膏燃,keyboardHidden則是用戶打開手機(jī)硬件鍵盤;

進(jìn)程的生命周期

Android系統(tǒng)嘗試盡可能長地保持應(yīng)用程序進(jìn)程何什,但最終需要在內(nèi)存不足時刪除舊進(jìn)程组哩。如活動生命周期中所述,關(guān)于要刪除哪個進(jìn)程的決策與用戶與其交互的狀態(tài)密切相關(guān)。一般來說伶贰,一個進(jìn)程可以基于其中運(yùn)行的Activity有四個狀態(tài)蛛砰,這里按照重要性的順序列出。系統(tǒng)將在殺死更重要的進(jìn)程(第一個進(jìn)程)之前殺死不太重要的進(jìn)程(最后一個進(jìn)程)幕袱。

  • 前臺Activity(在該用戶當(dāng)前交互的屏幕的頂部的Activity)被認(rèn)為是最重要的暴备。如果它使用的內(nèi)存超過了設(shè)備可提供的,它的進(jìn)程會作為最后的手段被殺死们豌。通常設(shè)備這時候已經(jīng)到了內(nèi)存分頁狀態(tài)(memory paging state)的地步涯捻,終止一些前臺進(jìn)程是為了保證用戶界面的及時響應(yīng)。
  • 一個可見的Activity(即對用戶可見望迎,但不是在前臺的Activity障癌,例如一個位于前臺后面的對話框),被認(rèn)為是非常重要的辩尊,不會被殺死除非必須保持前臺運(yùn)行的Activity涛浙。
  • 一個背景Activity(Activity是對用戶不可見,并已暫停)已不再是關(guān)鍵摄欲,所以系統(tǒng)可以安全地殺死它的進(jìn)程回收內(nèi)存以提供內(nèi)存給其他前臺或可見的進(jìn)程轿亮。如果它的進(jìn)程需要被殺死,當(dāng)用戶后退回Activity(使它在屏幕上再次可見)時胸墙,通過onCreate(Bundle)方法里的Bundle恢復(fù)用戶最后離開這個Activity時的狀態(tài)我注,在Activity被銷毀時,會調(diào)用onSaveInstanceState(Bundle)方法存儲Activity的狀態(tài)到Bundle里迟隅。
  • 一個空的進(jìn)程沒有持有Activity或其他應(yīng)用程序組件(如Service或 BroadcastReceiver類)但骨。當(dāng)內(nèi)存變得很低時這些會被系統(tǒng)迅速殺死。因此智袭,在Activity之外執(zhí)行的任何后臺操作必須通過Activity上下文(Context)持有的BroadcastReceiver或Service中執(zhí)行奔缠,以確保系統(tǒng)知道它需要保持您的進(jìn)程。

有時吼野,一個Activity可能需要做一個長期運(yùn)行的操作校哎,它獨(dú)立于Activity生命周期本身而存在。例如可以是允許你將圖片上傳到網(wǎng)站的相機(jī)應(yīng)用瞳步。上傳可能需要很長時間闷哆,應(yīng)用程序應(yīng)允許用戶在上傳時離開應(yīng)用。要完成此操作谚攒,你的Activity應(yīng)該啟動一個Service進(jìn)行上傳阳准。這允許系統(tǒng)在上傳的持續(xù)時間內(nèi)正確地優(yōu)先考慮進(jìn)程(認(rèn)為它比其他非可見應(yīng)用程序更重要)氛堕,而與原始Activity是暫停(paused)馏臭,停止(stopped)還是結(jié)束(finished)無關(guān)。

本文大部分參考翻譯自谷歌API文檔,并且自己整理補(bǔ)充了一些內(nèi)容括儒,以下是資料鏈接:
[https://developer.android.google.cn/reference/android/app/Activity.html]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绕沈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子帮寻,更是在濱河造成了極大的恐慌乍狐,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件固逗,死亡現(xiàn)場離奇詭異浅蚪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)烫罩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門惜傲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贝攒,你說我怎么就攤上這事盗誊。” “怎么了隘弊?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵哈踱,是天一觀的道長。 經(jīng)常有香客問我梨熙,道長开镣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任串结,我火速辦了婚禮哑子,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肌割。我一直安慰自己卧蜓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布把敞。 她就那樣靜靜地躺著弥奸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奋早。 梳的紋絲不亂的頭發(fā)上盛霎,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機(jī)與錄音耽装,去河邊找鬼愤炸。 笑死,一個胖子當(dāng)著我的面吹牛掉奄,可吹牛的內(nèi)容都是我干的规个。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼诞仓!你這毒婦竟也來了缤苫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤墅拭,失蹤者是張志新(化名)和其女友劉穎活玲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谍婉,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舒憾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了穗熬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片珍剑。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖死陆,靈堂內(nèi)的尸體忽然破棺而出招拙,到底是詐尸還是另有隱情,我是刑警寧澤措译,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布别凤,位于F島的核電站,受9級特大地震影響领虹,放射性物質(zhì)發(fā)生泄漏规哪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一塌衰、第九天 我趴在偏房一處隱蔽的房頂上張望诉稍。 院中可真熱鬧,春花似錦最疆、人聲如沸杯巨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽服爷。三九已至,卻和暖如春获诈,著一層夾襖步出監(jiān)牢的瞬間仍源,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工舔涎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笼踩,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓亡嫌,卻偏偏與公主長得像嚎于,于是被迫代替她去往敵國和親桶至。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一匾旭、概述 Activity 作為與用戶交互的一個窗口,是使用非常頻繁的一個基本組件圃郊。Android系統(tǒng)是通過Act...
    三也視界閱讀 2,234評論 3 11
  • 本篇博客是筆者看過《Android開發(fā)藝術(shù)探索》才寫的价涝,有些是借鑒了此本書的內(nèi)容,當(dāng)有些內(nèi)容進(jìn)行了精進(jìn)持舆。 Acti...
    ClAndEllen閱讀 3,433評論 1 27
  • 這是我第三遍看《Android開發(fā)藝術(shù)探索》這本書了色瘩,從第一遍看的云里霧里,第二遍略微明白之后逸寓,我決定看第三遍居兆,并...
    陳添閱讀 863評論 2 8
  • 一本android開發(fā)程序員必讀的一本書,感謝任玉剛大佬的分享 一竹伸、Activity的生命周期全面分析 典型情況下...
    kongjn閱讀 544評論 1 3
  • 啟動與銷毀Activity 不同于使用 main() 方法啟動應(yīng)用的其他編程范例泥栖,Android 系統(tǒng)會通過調(diào)用對...
    安卓Boy閱讀 1,775評論 3 5