Android Activity

Android 四大組件 —— Activity

Actvity是Android中的四大組件之一,平常我們在手機一個用程序上所看的界面就是 Activity 的表現形式。而且 Activity 也是用戶唯一能夠感知到的組件,每一個UI的界面就是通過 Activity 顯示在屏幕上的,平常我們在軟件裏進行的各種頁面的切換很大一部分是不同 Activity 的跳轉。

我們在日常生活中不可避免的打開很多個不同的應用, Activity 的生命週期便是從我們點開圖標的那一瞬間開始的。,Google官方給出了Activity的生命週期圖,如下:

alt text

先來看看它的幾個回調方法:

  • onCreate():此方法在活動創建時被觸發,此時活動處於創建狀態,一般 Activity 的一些初始化的工作在該方法中執行,且在生命週期內只會執行一次。在該方法調用 setContentView 中進行 View 的創建。
  • onStart():這個方法緊接着 onCreate ,此時已經是可以看到活動的了,但是無法進行交互。此時 Activity 處於啓動的狀態。緊接着會回調 onResume() 。
  • onResume():此時 Activity 處於 Resume 狀態,位於前臺完全可見也可以進行交互,我們看到的界面便是 Activity 保持在 onResume() 狀態。該方法之後是 onPause() 方法。
  • onPause():該方法是在 onResume 之後執行的,此時活動處於暫停狀態,不在位於前臺,可見但是無法交互。這個方法的執行時間非常短,因此不應該在此方法中執行重量級的資源釋放。
  • onStop():此時活動對用戶已經不可見了。緊接着會回調 onRestart() 或者 onDestory()。此時 Activity 處於 Stopped 狀態,活動的控件實例還是存在的,只是沒有被顯示。此方法中可以釋放對用戶不可見時的資源。也可以在此方法中進行數據的保存。
  • onRestart():表示 Activity 從停止狀態重新啓動。後面會回調 onStart()
  • onDestroy():活動被銷燬,這是系統生命週期的最後一個回調。一般在這個回調中進行釋放所有還未釋放的資源。

用戶打開和關閉應用程序的過程其實就是 Activity 在不同的狀態之間進行切換的過程。我們所做的就是在正確的狀態下執行需要的邏輯。

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

  • 正常情況下就是用戶正常打開應用,是用完之後按返回鍵退出,以上的回調方法執行順序如下:
    onCreate -> onStart -> onResume -> 用戶操作 -> onPause -> onStop -> onDestory
  • 當應用在啓動或者用戶使用的過程中發生了什麼意外,就是異常情況下的生命週期,異常情況下的生命週期要分情況討論:
    • 系統配置發生改變:比如屏幕的方向發生旋轉、該改變語言環境,或者輸入設備發生更改。當這些發生時, Activity 會被銷燬和重建, Activity 會執行onPause -> onStop -> onDestory -> onCreate -> onStart -> onResume
    • 手機變爲多窗口:Android 7.0 以後,增加了一個“多窗口”模式,應用程序進入多窗口模式或者在多窗口模式中改變大小都會引發系統配置的更改,可以在代碼中自行處理配置更改,也可以對 Activity 進行銷燬和重建
    • 當前的 Actiivty 被新的 Activity 或者 Dialog 所部分覆蓋。這種情況下當前的 Activity 會回調 onPause 方法。當新的 Activity 退出或者 Dialog 消失使會重新調用 onResume 方法。如果完全覆蓋則會調用 onStop 方法,再回到該界面時則會回調 onStart 。
    • 系統的內存不足時,會殺死後臺的進程來確保前臺應用的正常運行。

關於系統配置改變時 Activity 重建的情況,Android 提供了一個屬性用於在指定屬性發生改變時不重建 Activity,該屬性爲: android:configChanges ,不同的值用“|”連接。該屬性的值如下:

  • mcc:SIM卡唯一標識IMSI(國際移動用戶識別碼)中的代碼,有三位數組成,中國爲460,此項標識mcc代碼發生了改變
  • mnc:SIM卡唯一標識了IMSI(國際移動用戶識別碼)中的運營商代碼,由兩位數組成,中國移動TD系統爲00,中國聯通爲01,中國電信爲03,此項標識mnc發生了改變
  • locale:設備本地位置發生了改變,一般指切換了系統語言
  • touchscreen:觸摸屏發生了改變,這個很費解,正常情況下無法發生,可以忽略它
  • keyboard:鍵盤類型發生了改變,比如用戶使用了外插鍵盤
  • keyboardHidden:鍵盤的可問性發生了改變,比如用戶調出了鍵盤
  • navigation:系統導航方式發生了改變,比如採用了軌跡球導航,這個很難發生,可以忽略它
  • screenLayout:屏幕布局發生了改變,很可能是用戶激活了另一個顯示設備
  • fontStyle:系統的字體縮放比例發生了改變,比如用於選擇了一個新的字號
  • uiMode:用戶界面模式發生了改變,比如是否開啓了夜間模式(API 8添加)
  • orientation:屏幕方向發生了改變,這個是最常用的,比如旋轉了手機屏幕
  • screenSize:當屏幕的尺寸信息發生了改變,當旋轉設備屏幕時,屏幕尺寸會發生變化,這個選項比較特殊,它和編譯選項有關,當編譯選項中的minSdkVersion和targetSdkVersion均低於13時,此選項不會導致Activity重啓,否則會導致Activity重啓(API 13重新添加)
  • smallestScreenSize:設備的物理尺寸發生了改變,這個項目和屏幕的方向沒有關係,僅僅在實際的物理屏幕尺寸改變時的時候發生,比如用戶切換到了外部的顯示設備,這個選項和screenSize一樣,這個選項不會導致Activity重啓否則會導致Activity重啓
  • layoutDirection:當佈局發現發生變化,這個屬性用的比較少,正常情況下無需修改佈局的layoutDirection屬性(API 17時添加)

我們常用的只有 locale 、orientation 和 keyboardHidden 這三個選項。當系統配置發生改變時,系統會回調onConfigurationChanged方法。另外,Android 3.2 之後,當設備的方向發生改變時,同時也會觸發屏幕的尺寸信息改變,因此 “orientation” 要與 “screenSize” 一起使用纔會生效

關於系統進程的優先級,Android 根據進程中運行的組件以及其所處的狀態對進程做了一個優先級的劃分(從高到低):

  • 前臺進程:用戶當前正在使用的進程。一個前臺進程需要具備以下條件的任意一個或者幾個:
    • 有一個顯示在當前用戶屏幕的最上面的 Activity ,並且正在與用戶進行交互(此時 onResume 已經被調用了)
    • 進程中的有一個廣播接收器正在執行 onReceive 方法。
    • 進程中有一個服務正在執行它的某一個回調( onCreate, onStart() 或者 onDestory())
  • 可見進程:正在執行用戶感知得到的任務。它需要具備以下條件的一個或幾個:
    • 該進程中運行的一個 Activity 對用戶可見但不處於交互狀態。例如 Activity 被部分覆蓋的情況
    • 該進程中有一個運行在前臺的服務(正在執行 Service.startForeground() 方法。)
    • 承載一個用於執行特定功能的系統服務,比如動態壁紙,輸入法等等,這些服務是能夠被用戶感知的。
  • 服務進程:該進程包含一個已啓動的後臺服務,這些服務一般在後臺執行一些用戶所關心的任務(比如網絡數據的上傳和下載)。在 Android 會對運行時間過長的服務進行降級以避免服務長時間運行而導致內存泄漏或者內存被大量佔用。
  • 緩存進程:該進程在系統中是可有可無的,因此在系統需要內存的時候會殺死。這些進程一般包含大量對用戶不可見的 Activity 。系統有一個列表用於保存這些緩存進程,該列表中的最後一個進程是最先被系統回收的進程。

注:進程之間的依賴性對進程的優先級也會有影響。比如進程 A 綁定到帶有 Context.bind_auto_create標誌的服務,那麼該服務所在的進程的優先級至少是和 A 進程的優先級一樣。

參考:

《Android 開發藝術探索》第一章

Android Developer Activity


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章