Activity的生命週期和啓動模式

《Android開發藝術探索》筆記——第一章 Activity的生命週期和啓動模式

1. Activity的生命週期

1)正常情況下
  • 第一次啓動

onCreate --> onStart --> onResume

  • 用戶打開新的Activity或者切換到桌面

onPause --> onStop

如果新Activity是透明主題,那麼不會調onStop

  • 用戶再次回到原Activity

onRestart --> onStart --> onResume

  • 用戶back鍵回退

onPause --> onStop --> onDestroy

  • A、B兩個Activity 跳轉變化

    進入A

A onCreate --> A onStart --> A onResume

​ A跳轉B

A onPause --> B onCreate --> B onStart --> B onResume --> A onStop

​ B返回A

B onPause --> A onRestart --> A onStart --> A onREsume --> B onStop --> B onDestroy

​ A back

A onPause --> A onStop --> A onDestroy

2)異常情況下

Activity在異常情況下終止,系統會調用onSaveInstanceState來保存當前Activity的狀態,這個方法的調用時機是在onStop之前,和onPause沒有既定的時序關係。恢復時調用onRestoreINstanceState,調用時機在onStart之後。

onPause–onSaveInstanceState–onStop–onDestory–onCreate–onStart–onResume

3)注意點
  • 舊Activity的onPause先調用,新Activity才啓動

  • onStart和onStop
    分別代表了Activity已經處於可見狀態和不可見狀態,此時的Activity未處在前臺,不可以與用戶交互,可多次被調用,期間Activity處於可見(visable lifetime)狀態。

  • onResume和onPause
    分別代表了Activity已經進入前臺獲得焦點和退出前臺失去焦點,此時的Activity是可以和用戶交互的,可多次被調用,期間的Activity處於前臺(foreground lifetime)狀態。

  • 彈出一個Dialog時,onPause會調用嗎?什麼情況下會,什麼情況下不會?

    如果彈出的是本Activity的Dialog,並不會有任何生命週期方法調用。Dialog是一個View,它本身就依附在Acitivty上,可以理解爲是屬於本Activity的,所以它的焦點也自然是本Activity的焦點,自然不會有什麼生命週期方法調用了。如果其他Activity的Dialog彈出了,onPause纔會調用

  • Activity調用了onDestory方法,就會在Activity的任務棧消失嗎?

    什麼時候onDestory會被調用呢?

    可以分爲兩大類:1.點擊了back鍵 2.Activity被意外銷燬

    點擊back鍵相當於調用了finish()方法,通常來說finish
    方法會至少有兩個目的,一是將Activity從返回棧中退出,二是調用onDestory方法(未必是及時調用)
    而直接調用onDestory,是不會將Activity在任務棧中清除的。

2. Activity 的啓動模式

1)standard 標準模式

系統的默認模式,每次啓動都創建一個新的實例,運行在啓動它的那個Activity所在的棧中,用ApplicationContext去啓動會報錯,因爲Context沒有任務棧,這時需要爲待啓動的Activity指定 FLAG_ACTIVITY_NEW_TASK,相當於singleTask

2)singleTop 棧頂複用模式

如果新Activity已經位於任務棧的棧頂,那麼此Activity不會被創建,它的onNewIntent方法會被回調,onCreate、onStart方法不會被調用

3)singleTask 棧內複用模式

只要Activity在棧中存在,那麼多次啓動都不會重新創建實例,調用時調到棧頂,singleTask具有clearTop的效果,其上Activity被全部出棧,回調onNewIntent

4)singleInstance 單實例模式

加強的singleTask,具有此種模式的Activity只能單獨地位於一個任務棧中

5)注意
  • 啓動後臺任務棧的Activity時,整個後臺任務棧都會被切換到前臺
  • TaskAffinity 參數標識了一個Activity所需要的任務棧的名字;它和singleTask 啓動模式配對使用時,它是具有該模式的Activity的目前任務棧的名字,待啓動的Activity會運行在,名字和TaskAffinity相同的任務棧中
  • 啓動模式設置代碼優先級高於Manifest中配置,但是代碼無法指定singleInstance模式,manifest無法直接設定 FLAG_ACTIVITY_CLEAR_TOP

3. Activity中常用的標誌位

1)FLAG_ACTIVITY_NEW_TASK
2)FLAG_ACTIVITY_SINGLE_TOP
3)FLAG_ACTIVITY_CLEAR_TOP

和 FLAG_ACTIVITY_NEW_TASK 配合使用,被啓動的Activity如果已經存在,系統會調用它的onNewIntent;如何被啓動的Activity採用standard模式,那麼它連同它之上的Activity都要出棧,系統會創建新的Activity實例並放入棧頂

4)FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

具有這個標記的Activity不會出現在歷史Activity的列表中

4. IntentFilter的匹配規則

IntentFilter中所設置的過濾信息有action、category、data

1)action 的匹配規則

匹配要求字符串值完全一樣,Intent中的action能夠和過濾規則中的任何一個action相同即可

2)category

Intent 中所有的 category都必須和過濾規則中的其中一個 category相同

3)data

由 mimeType 和 URI 組成,匹配要求Intent中的data能夠完全匹配過濾規則中的某一個data

4)使用 PackageManager 的 resolveActivity 方法或者 Intent 的 resloveActivity 方法判斷通過隱式要啓動的Activity是否爲null
5)不含有 DEFAULT 這個 category 的Activity 是無法接收隱式 Intent的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章