2019-04-29

Android 四大組件 —— Activity

Actvity是Android中的四大組件之一,平常我們?cè)谑謾C(jī)一個(gè)用程序上所看的界面就是 Activity 的表現(xiàn)形式。而且 Activity 也是用戶唯一能夠感知到的組件,每一個(gè)UI的界面就是通過 Activity 顯示在屏幕上的,平常我們?cè)谲浖镞M(jìn)行的各種頁面的切換很大一部分是不同 Activity 的跳轉(zhuǎn)。

我們?cè)谌粘I钪胁豢杀苊獾拇蜷_很多個(gè)不同的應(yīng)用, Activity 的生命周期便是從我們點(diǎn)開圖標(biāo)的那一瞬間開始的。,Google官方給出了Activity的生命周期圖,如下:

先來看看它的幾個(gè)回調(diào)方法:

  • onCreate():此方法在活動(dòng)創(chuàng)建時(shí)被觸發(fā),此時(shí)活動(dòng)處于創(chuàng)建狀態(tài),一般 Activity 的一些初始化的工作在該方法中執(zhí)行,且在生命周期內(nèi)只會(huì)執(zhí)行一次。在該方法調(diào)用 setContentView 中進(jìn)行 View 的創(chuàng)建。

  • onStart():這個(gè)方法緊接著 onCreate ,此時(shí)已經(jīng)是可以看到活動(dòng)的了,但是無法進(jìn)行交互。此時(shí) Activity 處于啟動(dòng)的狀態(tài)。緊接著會(huì)回調(diào) onResume() 。

  • onResume():此時(shí) Activity 處于 Resume 狀態(tài),位于前臺(tái)完全可見也可以進(jìn)行交互,我們看到的界面便是 Activity 保持在 onResume() 狀態(tài)。該方法之后是 onPause() 方法。

  • onPause():該方法是在 onResume 之后執(zhí)行的,此時(shí)活動(dòng)處于暫停狀態(tài),不在位于前臺(tái),可見但是無法交互。這個(gè)方法的執(zhí)行時(shí)間非常短,因此不應(yīng)該在此方法中執(zhí)行重量級(jí)的資源釋放。

  • onStop():此時(shí)活動(dòng)對(duì)用戶已經(jīng)不可見了。緊接著會(huì)回調(diào) onRestart() 或者 onDestory()。此時(shí) Activity 處于 Stopped 狀態(tài),活動(dòng)的控件實(shí)例還是存在的,只是沒有被顯示。此方法中可以釋放對(duì)用戶不可見時(shí)的資源。也可以在此方法中進(jìn)行數(shù)據(jù)的保存。

  • onRestart():表示 Activity 從停止?fàn)顟B(tài)重新啟動(dòng)。后面會(huì)回調(diào) onStart()

  • onDestroy():活動(dòng)被銷毀,這是系統(tǒng)生命周期的最后一個(gè)回調(diào)。一般在這個(gè)回調(diào)中進(jìn)行釋放所有還未釋放的資源。

用戶打開和關(guān)閉應(yīng)用程序的過程其實(shí)就是 Activity 在不同的狀態(tài)之間進(jìn)行切換的過程。我們所做的就是在正確的狀態(tài)下執(zhí)行需要的邏輯。

Activity 的生命周期分為兩種情況:一種是正常情況下,一種是異常情況下。

  • 正常情況下就是用戶正常打開應(yīng)用,是用完之后按返回鍵退出,以上的回調(diào)方法執(zhí)行順序如下:

onCreate -> onStart -> onResume -> 用戶操作 -> onPause -> onStop -> onDestory

  • 當(dāng)應(yīng)用在啟動(dòng)或者用戶使用的過程中發(fā)生了什么意外,就是異常情況下的生命周期,異常情況下的生命周期要分情況討論:

    • 系統(tǒng)配置發(fā)生改變:比如屏幕的方向發(fā)生旋轉(zhuǎn)、該改變語言環(huán)境,或者輸入設(shè)備發(fā)生更改。當(dāng)這些發(fā)生時(shí), Activity 會(huì)被銷毀和重建, Activity 會(huì)執(zhí)行onPause -> onStop -> onDestory -> onCreate -> onStart -> onResume

    • 手機(jī)變?yōu)槎啻翱冢篈ndroid 7.0 以后,增加了一個(gè)“多窗口”模式,應(yīng)用程序進(jìn)入多窗口模式或者在多窗口模式中改變大小都會(huì)引發(fā)系統(tǒng)配置的更改,可以在代碼中自行處理配置更改,也可以對(duì) Activity 進(jìn)行銷毀和重建

    • 當(dāng)前的 Actiivty 被新的 Activity 或者 Dialog 所部分覆蓋。這種情況下當(dāng)前的 Activity 會(huì)回調(diào) onPause 方法。當(dāng)新的 Activity 退出或者 Dialog 消失使會(huì)重新調(diào)用 onResume 方法。如果完全覆蓋則會(huì)調(diào)用 onStop 方法,再回到該界面時(shí)則會(huì)回調(diào) onStart 。

    • 系統(tǒng)的內(nèi)存不足時(shí),會(huì)殺死后臺(tái)的進(jìn)程來確保前臺(tái)應(yīng)用的正常運(yùn)行。

關(guān)于系統(tǒng)配置改變時(shí) Activity 重建的情況,Android 提供了一個(gè)屬性用于在指定屬性發(fā)生改變時(shí)不重建 Activity,該屬性為: android:configChanges ,不同的值用“|”連接。該屬性的值如下:

  • mcc:SIM卡唯一標(biāo)識(shí)IMSI(國際移動(dòng)用戶識(shí)別碼)中的代碼,有三位數(shù)組成,中國為460,此項(xiàng)標(biāo)識(shí)mcc代碼發(fā)生了改變

  • mnc:SIM卡唯一標(biāo)識(shí)了IMSI(國際移動(dòng)用戶識(shí)別碼)中的運(yùn)營商代碼,由兩位數(shù)組成,中國移動(dòng)TD系統(tǒng)為00,中國聯(lián)通為01,中國電信為03,此項(xiàng)標(biāo)識(shí)mnc發(fā)生了改變

  • locale:設(shè)備本地位置發(fā)生了改變,一般指切換了系統(tǒng)語言

  • touchscreen:觸摸屏發(fā)生了改變,這個(gè)很費(fèi)解,正常情況下無法發(fā)生,可以忽略它

  • keyboard:鍵盤類型發(fā)生了改變,比如用戶使用了外插鍵盤

  • keyboardHidden:鍵盤的可問性發(fā)生了改變,比如用戶調(diào)出了鍵盤

  • navigation:系統(tǒng)導(dǎo)航方式發(fā)生了改變,比如采用了軌跡球?qū)Ш?,這個(gè)很難發(fā)生,可以忽略它

  • screenLayout:屏幕布局發(fā)生了改變,很可能是用戶激活了另一個(gè)顯示設(shè)備

  • fontStyle:系統(tǒng)的字體縮放比例發(fā)生了改變,比如用于選擇了一個(gè)新的字號(hào)

  • uiMode:用戶界面模式發(fā)生了改變,比如是否開啟了夜間模式(API 8添加)

  • orientation:屏幕方向發(fā)生了改變,這個(gè)是最常用的,比如旋轉(zhuǎn)了手機(jī)屏幕

  • screenSize:當(dāng)屏幕的尺寸信息發(fā)生了改變,當(dāng)旋轉(zhuǎn)設(shè)備屏幕時(shí),屏幕尺寸會(huì)發(fā)生變化,這個(gè)選項(xiàng)比較特殊,它和編譯選項(xiàng)有關(guān),當(dāng)編譯選項(xiàng)中的minSdkVersion和targetSdkVersion均低于13時(shí),此選項(xiàng)不會(huì)導(dǎo)致Activity重啟,否則會(huì)導(dǎo)致Activity重啟(API 13重新添加)

  • smallestScreenSize:設(shè)備的物理尺寸發(fā)生了改變,這個(gè)項(xiàng)目和屏幕的方向沒有關(guān)系,僅僅在實(shí)際的物理屏幕尺寸改變時(shí)的時(shí)候發(fā)生,比如用戶切換到了外部的顯示設(shè)備,這個(gè)選項(xiàng)和screenSize一樣,這個(gè)選項(xiàng)不會(huì)導(dǎo)致Activity重啟否則會(huì)導(dǎo)致Activity重啟

  • layoutDirection:當(dāng)布局發(fā)現(xiàn)發(fā)生變化,這個(gè)屬性用的比較少,正常情況下無需修改布局的layoutDirection屬性(API 17時(shí)添加)

我們常用的只有 locale 、orientation 和 keyboardHidden 這三個(gè)選項(xiàng)。當(dāng)系統(tǒng)配置發(fā)生改變時(shí),系統(tǒng)會(huì)回調(diào)onConfigurationChanged方法。另外,Android 3.2 之后,當(dāng)設(shè)備的方向發(fā)生改變時(shí),同時(shí)也會(huì)觸發(fā)屏幕的尺寸信息改變,因此 “orientation” 要與 “screenSize” 一起使用才會(huì)生效

關(guān)于系統(tǒng)進(jìn)程的優(yōu)先級(jí),Android 根據(jù)進(jìn)程中運(yùn)行的組件以及其所處的狀態(tài)對(duì)進(jìn)程做了一個(gè)優(yōu)先級(jí)的劃分(從高到低):

  • 前臺(tái)進(jìn)程:用戶當(dāng)前正在使用的進(jìn)程。一個(gè)前臺(tái)進(jìn)程需要具備以下條件的任意一個(gè)或者幾個(gè):

    • 有一個(gè)顯示在當(dāng)前用戶屏幕的最上面的 Activity ,并且正在與用戶進(jìn)行交互(此時(shí) onResume 已經(jīng)被調(diào)用了)

    • 進(jìn)程中的有一個(gè)廣播接收器正在執(zhí)行 onReceive 方法。

    • 進(jìn)程中有一個(gè)服務(wù)正在執(zhí)行它的某一個(gè)回調(diào)( onCreate, onStart() 或者 onDestory())

  • 可見進(jìn)程:正在執(zhí)行用戶感知得到的任務(wù)。它需要具備以下條件的一個(gè)或幾個(gè):

    • 該進(jìn)程中運(yùn)行的一個(gè) Activity 對(duì)用戶可見但不處于交互狀態(tài)。例如 Activity 被部分覆蓋的情況

    • 該進(jìn)程中有一個(gè)運(yùn)行在前臺(tái)的服務(wù)(正在執(zhí)行 Service.startForeground() 方法。)

    • 承載一個(gè)用于執(zhí)行特定功能的系統(tǒng)服務(wù),比如動(dòng)態(tài)壁紙,輸入法等等,這些服務(wù)是能夠被用戶感知的。

  • 服務(wù)進(jìn)程:該進(jìn)程包含一個(gè)已啟動(dòng)的后臺(tái)服務(wù),這些服務(wù)一般在后臺(tái)執(zhí)行一些用戶所關(guān)心的任務(wù)(比如網(wǎng)絡(luò)數(shù)據(jù)的上傳和下載)。在 Android 會(huì)對(duì)運(yùn)行時(shí)間過長的服務(wù)進(jìn)行降級(jí)以避免服務(wù)長時(shí)間運(yùn)行而導(dǎo)致內(nèi)存泄漏或者內(nèi)存被大量占用。

  • 緩存進(jìn)程:該進(jìn)程在系統(tǒng)中是可有可無的,因此在系統(tǒng)需要內(nèi)存的時(shí)候會(huì)殺死。這些進(jìn)程一般包含大量對(duì)用戶不可見的 Activity 。系統(tǒng)有一個(gè)列表用于保存這些緩存進(jìn)程,該列表中的最后一個(gè)進(jìn)程是最先被系統(tǒng)回收的進(jìn)程。

注:進(jìn)程之間的依賴性對(duì)進(jìn)程的優(yōu)先級(jí)也會(huì)有影響。比如進(jìn)程 A 綁定到帶有 Context.bind_auto_create標(biāo)志的服務(wù),那么該服務(wù)所在的進(jìn)程的優(yōu)先級(jí)至少是和 A 進(jìn)程的優(yōu)先級(jí)一樣。

參考:

《Android 開發(fā)藝術(shù)探索》第一章

Android Developer Activity

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容