一、什么是Activity?
Activity是Android組件中最基本也是最為常見用的四大組件之一?。
Activity中所有操作都與用戶密切相關(guān),是一個(gè)負(fù)責(zé)與用戶交互的組件,可以通過setContentView(View)來顯示指定控件。
在一個(gè)android應(yīng)用中,一個(gè)Activity通常就是一個(gè)單獨(dú)的屏幕,它上面可以顯示一些控件也可以監(jiān)聽并處理用戶的事件做出響應(yīng)。
二、 Activity的生命周期
2.1 典型情況下的生命周期:
onCreate:表示Activity正被創(chuàng)建??梢宰鲆恍?b>初始化的工作,比如調(diào)用setContentView加載界面布局、初始化數(shù)據(jù)。
onRestart:表示Activity正在重新啟動(dòng)。當(dāng)前Activity從不可見重新變?yōu)榭梢姞顟B(tài),就會(huì)調(diào)用onRestart。場景:用戶按Home鍵切換到桌面或用戶打開一個(gè)新的界面,然后重新回到這個(gè)頁面。
onStart:表示Activity正在被啟動(dòng),即將開始。可見,但未展示在前臺(tái),無法與用戶交互。
onResume:表示Activity獲得焦點(diǎn)。可見,并且出現(xiàn)在前臺(tái),可交互。
onPause:正在停止。此時(shí)Activity在前臺(tái)并可見,可做存儲(chǔ)數(shù)據(jù)、停止動(dòng)畫等工作,切勿執(zhí)行太耗時(shí)的操作。
onStop:即將停止。不可見,可做稍微重量級的回收工作,同樣不能太耗時(shí)。
onDestroy:即將被銷毀。做回收工作和最終的資源釋放。

onCreate、onDestroy 一對? 只調(diào)用一次。
onStart、onStop一對? 是否可見。
onResume、onPause一對? 是否在前臺(tái)。
2.1.1 Activity生命周期的切換過程:
Activity第一次啟動(dòng):onCreate->onStart->onResume
當(dāng)用戶打開新的Activity或者切換到桌面的時(shí)候:onPause->onStop
當(dāng)用戶返回原Activity:onRestart->onStart->onResume
按back鍵回退:onPause->onStop->onDestroy
在當(dāng)前Activity上打開新的Activity:舊onPause->新OnCreate->onStart->onResume->舊onStop

2.2 異常情況下的生命周期
情況一:資源相關(guān)的系統(tǒng)配置發(fā)生改變導(dǎo)致Activity被殺死并重新創(chuàng)建(比如屏幕旋轉(zhuǎn)導(dǎo)致的系統(tǒng)配置發(fā)生改變)
Activity被意外終止時(shí),才會(huì)調(diào)用onSaveInstanceState和onRestoreInstanceState去保存數(shù)據(jù)和恢復(fù)數(shù)據(jù),其他情況不會(huì)觸發(fā)這個(gè)過程。
系統(tǒng)配置發(fā)生改變但不希望重新創(chuàng)建Activity,可以給Activity指定configChanges屬性。比如不想讓Activity在屏幕旋轉(zhuǎn)時(shí)重新創(chuàng)建,可以在manifest中給當(dāng)前的Activity設(shè)置android:configChanges="orientation",不會(huì)調(diào)用onSaveInstanceState和onRestoreInstanceState去保存數(shù)據(jù)和恢復(fù)數(shù)據(jù),取而代之的是調(diào)用onConfigurationChanged。
configChanges? 常用參數(shù):

情況二:資源內(nèi)存不足導(dǎo)致低優(yōu)先級的Activity被殺死
Activity優(yōu)先級:
由高到低:前臺(tái)Activity > 可見但非前臺(tái)Activity(比如:Activity中彈出一個(gè)對話框,此時(shí)的Activity可見但無法與用戶交互)> 后臺(tái)Activity(執(zhí)行了onStop的Activity)
當(dāng)內(nèi)存不足時(shí),系統(tǒng)會(huì)按照優(yōu)先級去殺死目標(biāo)Activity所在的進(jìn)程,并在后續(xù)通過onSaveInstanceState和onRestoreInstanceState來存儲(chǔ)和恢復(fù)數(shù)據(jù)。如果一個(gè)進(jìn)程中沒有四大組件在執(zhí)行,那么將很快被系統(tǒng)殺死。
三、Activity的啟動(dòng)模式
3.1 四種啟動(dòng)模式(LaunchMode)
standard:標(biāo)準(zhǔn)模式,系統(tǒng)的默認(rèn)模式。
每次啟動(dòng)一個(gè)Activity都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例,不管這個(gè)實(shí)例是否已經(jīng)存在。被創(chuàng)建的實(shí)例符合典型的Activity生命周期。一個(gè)任務(wù)棧中可以有多個(gè)實(shí)例,每個(gè)實(shí)例也可以屬于不同的任務(wù)棧。在這種模式下,誰啟動(dòng)了這個(gè)Activity,那么這個(gè)Activity就運(yùn)行在啟動(dòng)它的那個(gè)Activity所在的棧中。

singleTop:棧頂復(fù)用模式
在這種模式下,如果新Activity已經(jīng)位于任務(wù)棧的棧頂,那么此Activity不會(huì)被重新創(chuàng)建,同時(shí)它的onNewIntent方法會(huì)被回調(diào),通過此方法的參數(shù)我們可以取出當(dāng)前請求的信息。如果新Activity的實(shí)例已經(jīng)存在但不是位于棧頂,那么新的Activity仍然會(huì)重建。
舉三個(gè)栗子來理解Activity的棧頂復(fù)用模式:
①一個(gè)棧內(nèi)有ABCD四個(gè)Activity,A位于棧底,D位于棧頂。此時(shí)啟動(dòng)D ,啟動(dòng)模式為SingleTop,因?yàn)镈在棧頂,D不會(huì)重新創(chuàng)建,那么棧內(nèi)情況仍為ABCD。
②同樣,一個(gè)棧內(nèi)有ABCD四個(gè)Activity,A位于棧底,D位于棧頂。啟動(dòng)D ,模式為standard(標(biāo)準(zhǔn)模式),因?yàn)槊看螁?dòng)一個(gè)Activity都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例,不管這個(gè)實(shí)例是否已經(jīng)存在,所以D會(huì)再次創(chuàng)建,那么棧內(nèi)的情況為ABCDD。
③同樣,一個(gè)棧內(nèi)有ABCD四個(gè)Activity,A位于棧底,D位于棧頂。啟動(dòng)C, 模式為SingleTop,因?yàn)镃不在棧頂,已經(jīng)存在,所以C會(huì)再次創(chuàng)建,那么棧內(nèi)的情況為ABCDC。

singleTask:棧內(nèi)復(fù)用模式
singleTask是一種單實(shí)例模式。此模式下,只要Activity在一個(gè)棧中存在,那么多次啟動(dòng)這個(gè)Activity都不會(huì)重新創(chuàng)建。
比如:Activity A以singleTask模式請求啟動(dòng),系統(tǒng)會(huì)先去尋找是否存在A想要的任務(wù)棧。如果不存在,就重新創(chuàng)建一個(gè)任務(wù)棧,然后創(chuàng)建A的實(shí)例,并放入到此棧中。如果存在A所需的任務(wù)棧,就看棧內(nèi)是否含有A的實(shí)例,若實(shí)例存在,系統(tǒng)就會(huì)把A調(diào)至棧頂并調(diào)用它的onNewIntent方法;如果實(shí)例不存在,就創(chuàng)建A的實(shí)例并把A壓入棧中。
舉個(gè)三個(gè)栗子來理解Activity的棧內(nèi)復(fù)用模式:
①已有任務(wù)棧S1,棧內(nèi)有ABC三個(gè)Activity,這個(gè)時(shí)候Activity D以singleTask模式請求啟動(dòng),其所需任務(wù)棧為S2,因?yàn)镾2和D的實(shí)例都不存在,所以系統(tǒng)會(huì)先創(chuàng)建任務(wù)棧S2,然后創(chuàng)建D的實(shí)例并入棧S2。

②已有任務(wù)棧S1,棧內(nèi)有ABC三個(gè)Activity,這個(gè)時(shí)候Activity D以singleTask模式請求啟動(dòng),其所需任務(wù)棧為S1,因?yàn)镾1已經(jīng)存在,所以系統(tǒng)就創(chuàng)建D的實(shí)例并入棧S1。

③已有任務(wù)棧S1,棧內(nèi)有ADBC四個(gè)Activity,此時(shí)棧內(nèi)Activity D以singleTask模式請求啟動(dòng),因?yàn)镈實(shí)例已經(jīng)存在,所以不會(huì)重建。為了把D切到棧頂,D上面的Activity會(huì)依次出棧。最終棧內(nèi)只有AD。

singleInstance:單實(shí)例模式
singleInstance模式具有singleTask模式的所有特性,此外singleInstance模式的Activity只能單獨(dú)地位于一個(gè)任務(wù)棧中。
比如:Activity是singleInstance模式,A啟動(dòng)后,系統(tǒng)為它創(chuàng)建一個(gè)新的任務(wù)棧,然后A獨(dú)自在這個(gè)棧中,由于棧內(nèi)復(fù)用特性,后續(xù)的請求均不會(huì)創(chuàng)建新的Activity,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀了。
3.1.1 如何給指定的Activity指定啟動(dòng)模式?
①在AndroidMenifest指定Activity的啟動(dòng)模式

②通過在Intent中設(shè)置標(biāo)志位

二者區(qū)別:

3.1.2? Activity的Flags

這里特別提下FLAG_ACTIVITY_CLEAR_TOP的一個(gè)使用場景,現(xiàn)有四個(gè)頁面ABCD,頁面A跳轉(zhuǎn)至B,B到C,C到D,在D頁面操作交易成功后返回至A頁面,注意,D頁面若是按返回鍵則原路返回至C、B、A,所以在B、C、D頁面跳轉(zhuǎn)就finish的方案不符合需求。這里FLAG_ACTIVITY_CLEAR_TOP就派上用場了,具體用法見截圖:

3.1.3 IntentFilter 的匹配規(guī)則
啟動(dòng)Activity分為顯示和隱式調(diào)用。隱式調(diào)用需要Intent能夠匹配目標(biāo)組件的IntentFilter中所設(shè)置的過濾信息,如果不匹配將無法啟動(dòng)目標(biāo)Activity。
action的匹配規(guī)則:要求Intent中的action存在且必須和過濾規(guī)則中的其中一個(gè)action相同。action是字符串,區(qū)分大小寫。
category的匹配規(guī)則:Intent中的category可以不存在,如果存在,則每個(gè)Intent中的category都要與規(guī)律規(guī)則的一致。
data的匹配規(guī)則:如果過濾規(guī)則中定義了data,那么Intent中也要定義可匹配的data。
data的結(jié)構(gòu):mimeType和URI。
mineType:指媒體類型,可以表示圖片、文本、視頻等媒體格式。比如image/jpeg、audio/mpeg4-generic、video/*等。
URI的結(jié)構(gòu):

感謝您耐心地讀到最后。在此特別說明一下,這是我拜讀大佬任玉剛老師的《Android 開發(fā)藝術(shù)探索》一書整理出來的讀書筆記,文字、截圖都是我辛苦整理出來的,相信大方的你會(huì)點(diǎn)贊的,對嗎?