Activity知識點詳解

摘自:https://www.cnblogs.com/Robin132929/p/12081190.html

Activity知識點詳解

一、什麼是Activity

官方解釋:

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應用。

二、生命週期

生命週期作爲Activity老生常談的知識點是我們必須要熟練掌握的。這裏要分兩種情況去理解掌握:正常情況下的生命週期和異常情況下的生命週期。

正常情況下的生命週期

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

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

異常情況下的生命週期

我們主要注意以下兩種情況下的生命週期:

系統配置發生變化

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

內存緊張導致Activity被殺死

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

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

最後關於這兩個函數的回調時機,系統版本不同會有一些差異:
1、 api < 11,onSaveInstance在onPause之前執行
2、11 <= api < 28,onSaveInstance在onPause之後,onStop之前執行
3、api >= 28,onSaveInstance在onStop之後執行

三、啓動方式

分類一

顯示啓動

指明ComponentName有明確的啓動目標

隱式啓動

未指明ComponentName,通過匹配intentfilter找到可以啓動的目標

分類二

不帶返回值

通過startActivity

帶返回值

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

四、任務棧

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還有兩點要注意:
1、根activity的taskAffinity可以決定task的“名字”,activity在啓動時和re-parent時需要根據taskAffinity來確定該activity會出現在哪個task
2、優先級是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的啓動模式判斷會如何啓動

五、相關問題

onWindowFocusChanged

在Activity窗口獲得或失去焦點時被調用,
1、創建時首次呈現在用戶面前;
2、當前Activity被其他Activity覆蓋;
3、當前Activity轉到其他Activity或按Home鍵回到主屏,自身退居後臺;
4、用戶退出當前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的生命週期是怎樣變化的

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