Activity知識點詳解

Activity知識點詳解

1、什麼是Activity

官方解釋:android

The Activity class is a crucial component of an Android app, and the way activities are launched and put together is a fundamental part of the platform’s application model. Unlike programming paradigms in which apps are launched with amain()method, the Android system initiates code in an Activity instance by invoking specific callback methods that correspond to specific stages of its lifecycle.
Activity是Android應用的重要組成部分,它的啓動和組合方式是Android應用程序模型的一個基本部分。與使用 main ()方法啓動應用程序的編程範例不一樣,Android 系統經過調用與其生命週期的特定階段相對應的特定回調方法來啓動 Activity 實例中的代碼。
咱們在平常的開發中接觸最多的可能就是Activity了,對於Activity個人理解是它做爲Android四大組件之一,主要是給咱們提供界面的展現和用戶交互。。這裏要說下Android的四大組件,Activity、Service、Brocast、ContentProvider功能各不相同可是稱它們爲四大組件主要是它們四個都是Android應用的入口。咱們都知道Java是採用main ()方法啓動應用程序的,可是Android並無採用這種方式,Android設計了四個組件以這些組件爲入口來啓動一個Android應用。面試

2、生命週期

生命週期做爲Activity老生常談的知識點是咱們必需要熟練掌握的。這裏要分兩種狀況去理解掌握:正常狀況下的生命週期和異常狀況下的生命週期。編程

正常狀況下的生命週期

這能夠說是Activity最基本的知識點了在此就不展開了,貼張圖
Activity生命週期api

再次補充一個關於生命週期的問題就是處於哪些生命週期時是能夠被殺死的。
onCreate、onStart()、onRestart()、onResume()當Activity處於這些生命週期時是不可被kill的。onPause()在Honeycomb(3.X版本)以前是能夠被kill的,而從Honeycomb開始系統在Activity回調onStop()
以前是不會殺死Activity的,由於這樣能夠確保在異常狀況下onsaveinstancestate被調用,保存狀態。
(Android P開始onsaveinstancestate在onStop()以後被調用)app

異常狀況下的生命週期

咱們主要注意如下兩種狀況下的生命週期:ide

系統配置發生變化

好比常見的如屏幕方向發生變化,配置發生變化是會致使Activity銷燬重建的,若是咱們想保持以前的Activity不被銷燬那麼咱們能夠在manifest中設置對應的配置信息 ,以後當其變化時會觸發onConfigurationChanged回調此時是不會銷燬重建的。可是要注意的是觸發回調時當前組件(Activity)必須還在運行 若是組件被暫停 那麼是不會觸發回調的 。函數

內存緊張致使Activity被殺死

由於Android整體資源有限當內存緊張時系統會根據必定的優先級殺死一些Activity。這裏的優先級依次是:前臺Activity>可見Activity>後臺Activity>空進程。設計

除此以外咱們還要了解onsaveinstancestate/onrestoreinstancestate回調。
onsaveinstancestate是Activity由於異常被系統kill時用來保存當前Activity的有關狀態和數據的,咱們也能夠在該回調中保存咱們想要保存的數據以防止Activity由於異常被殺死而丟失數據。以後系統會在合適的時機重建該Activity此時就會觸發onrestoreinstancestate回調,在該回調裏咱們能夠拿到以前保存的狀態和數據進行恢復(在oncreate中也能夠拿到保存的數據不過須要進行判空,因此仍是推薦在onrestoreinstancestate進行恢復)。rest

最後關於這兩個函數的回調時機,系統版本不一樣會有一些差別:
一、 api < 11,onSaveInstance在onPause以前執行
二、11 <= api < 28,onSaveInstance在onPause以後,onStop以前執行
三、api >= 28,onSaveInstance在onStop以後執行code

3、啓動方式

分類一

顯示啓動

指明ComponentName有明確的啓動目標

隱式啓動

未指明ComponentName,經過匹配intentfilter找到能夠啓動的目標

分類二

不帶返回值

經過startActivity

帶返回值

startActivityForResult啓動並在onActivityResult中接收返回的結果。

4、任務棧

Task是用戶在執行某項任務時與之交互的Activity的集合。按照每一個Activity打開的順序排列在一個堆棧(先進後出)。通常來講處在棧頂的Activity是正在前臺的Activity。
總結Activity和Task的默認行爲:

  • 當Activitya 啓動Activity b 時,Activity a 中止,但系統保持其狀態(如滾動位置和輸入到表單中的文本)。 若是用戶按下Back鍵回來那麼a 恢復其狀態,b被彈出Task並被銷燬。
  • 當用戶經過按下Home button當前Activity被中止而且它的任務進入後臺。 系統保留任務中每一個Activity的狀態。 若是用戶稍後經過選擇啓動該Task的啓動圖標恢復該任務,則該Task將到達前臺並恢復堆棧頂部的Activity。
  • Activity能夠被屢次實例化,同時能夠從其餘Task中實例化

通常而言咱們不須要干預Task的默認行爲,可是咱們也能夠經過如下方法去幹預:

taskAffinity

Affinity表示Activity但願屬於哪一個Task。 默認狀況下,來自同一個應用程序的全部Activity彼此都有相同的Affinity。能夠設置Taskaffinity 屬性來自定義Affinity。task自身的affinity決定於根Activity的affinity值也就是說同一個task中的全部Activity具備相同的affinity。
affinity在什麼場合應用呢?
1.根據affinity從新爲Activity選擇宿主task(與allowTaskReparenting屬性配合工做);
2.啓動一個Activity過程當中Intent使用了FLAG_ACTIVITY_NEW_TASK標記,根據affinity查找或建立一個新的具備對應affinity的task
Affinity還有兩點要注意:
一、根activity的taskAffinity能夠決定task的「名字」,activity在啓動時和re-parent時須要根據taskAffinity來肯定該activity會出如今哪一個task
二、優先級是activity中指定的taskAffinity>application中指定的taskAffinity>默認的包名

launchMode

Android提供了四種啓動模式:

  • standard
    默認模式 該模式下每次啓動activity都會建立新的activity實例。特殊狀況,若是在Service或Application中啓動一個Activity,其並無所謂的任務棧,可使用標記位Flag來解決。解決辦法:爲待啓動的Activity指定FLAG_ACTIVITY_NEW_TASK標記位,建立一個新棧。
  • singleTop
    啓動一個activity若是該activity實例已經已在棧頂則複用並回調onnewintent。應用場景 推送跳轉activity
  • singleTask
    啓動一個activity時會先找本身所屬的Task,若是該Task已經存在那麼查看Task中是否有該activity實例 有則複用並回調onnewintent
    若是所屬的Task還未建立那麼就先建立Task而後再建立Activity實例併入棧 因此說singleTask 啓動模式的activity 是全局單例的。應用場景 app主頁
  • singleInstance
    能夠看作是singleTask的增強版,改啓動模式下每次都會啓動一個新的Task並將activity實例放到Task 而且Task中只有這一個activity實例。應用場景 呼叫來電。

    activity attributes或者intent flags

  • android:allowTaskReparenting
    這個屬性用來標記一個Activity實例在當前應用退居後臺後,是否能從啓動它的那個task移動到有共同affinity的task,「true」表示能夠移動,「false」表示它必須呆在當前應用的task中,默認值爲false 從新宿主的操做發生在應用退後臺再次重啓過程當中

  • android:alwaysRetainTaskState
    若是用戶長時間離開Task,系統將清除除根Activity之外的全部Activity。 當用戶再次返回Task時,只恢復根Activity。可是設置該屬性爲true後就不會發生清除,即便在很長一段時間以後,任務仍然保留其堆棧中的全部活動。

  • android:clearTaskOnLaunch
    在Task的根Activity中,只要用戶離開Task並返回到該Task,堆棧就會被清除到根Activity。用戶老是返回到Task的初始狀態,即便離開Task只有一下子。

  • android: finishOnTaskLaunch
    它做用於一個單一的Activity,而不是一個完整的Task。 它會致使任何Activity消失,包括根Activity。用戶離開,而後返回到Task,則該Task再也不存在。

  • FLAG_ACTIVITY_NEW_TASK
    其效果與指定Activity爲singleTask模式一致。系統會尋找或建立一個新的task來放置目標Activity,尋找時依據目標Activity的taskAffinity屬性進行匹配,若是找到一個task的taskAffinity與之相同,就將目標Activity壓入此task中,若是查找無果,則建立一個新的task,並將該task的taskAffinity設置爲目標Activity的taskActivity,將目標Activity放置於此task

  • FLAG_ACTIVITY_SINGLE_TOP
    其效果與指定Activity爲singleTop模式一致。

  • FLAG_ACTIVITY_CLEAR_TOP
    具備此標記位的Activity,當它啓動時,在同一個任務棧中全部位於它上面的Activity都要出棧。若是和singleTask模式一塊兒出現,若被啓動的Activity已經存在棧中,則清除其之上的Activity,並調用該Activity的onNewIntent方法。若是被啓動的Activity採用standard模式,那麼該Activity連同之上的全部Activity出棧,而後建立新的Activity實例並壓入棧中。若是和FLAG_ACTIVITY_NEW_TASK 一塊兒使用時,則是一種在另外一個Task中定位現有Activity並將其放置在可以響應該意圖的位置的方法。

  • FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    若是一個Intent中包含此屬性,則它轉向的那個Activity以及在那個Activity其上的全部Activity都會在task重置時被清除出task

最後說明下activity啓動時如何選擇task:

  1. 先判斷target activity可否在新task中啓動
    singleTask/singleInstance的activity自己具備在新task中啓動的能力,standard/singleTop的activity要想擁有在新task中啓動的能力,須要在設置Intent.FLAG_ACTIVITY_NEW_TASK

  2. 判斷target activity所在task
    找一個taskAffinity的task去啓動,找不到就新建一個(這裏會忽略了singleInstance獨佔的task)

  3. 根據TargetActivity的啓動模式判斷會如何啓動

5、相關問題

onWindowFocusChanged

在Activity窗口得到或失去焦點時被調用,
一、建立時首次呈如今用戶面前;
二、當前Activity被其餘Activity覆蓋;
三、當前Activity轉到其餘Activity或按Home鍵回到主屏,自身退居後臺;
四、用戶退出當前Activity。

以上幾種狀況都會調用onWindowFocusChanged,而且當Activity被建立時是在onResume以後被調用,當Activity被覆蓋或者退居後臺或者當前Activity退出時,它是在onPause以後被調用
這個方法在某種場合下仍是頗有用的,例如程序啓動時想要獲取視特定視圖組件的尺寸大小,在onCreate中可能沒法取到,由於窗口Window對象還沒建立完成,這個時候咱們就須要在onWindowFocusChanged裏獲取

其餘應用問題:

  1. activity間傳遞數據
  2. 知曉當前activity
  3. 關閉全部activity
  4. 雙擊退出app
  5. 保存activity狀態

    面試常見知識點

    Activity A跳轉到Activity B 二者經歷怎樣的生命週期 未配置configchanges狀況下屏幕發生旋轉時 當前Activity的生命週期是怎樣變化的

相關文章
相關標籤/搜索