Android 開發藝術探索 - 讀書筆記之第一章 Activity 的生命周期和啟動模式

1.1 Activity 的生命周期全面分析

1.1.1 典型情況下的生命周期分析

  • onPause: 正在停止,正常情況下緊接著 onStop 就會被調用,然后新的 Activity 執行 onResume; 如果新 Activity 采用了透明主題,則不會調用 onStop,因為 onStop 意味著不可見
  • 按 back 鍵回退時,回調 onPause -> onStop -> onDestroy
  • 生命周期的配對
    • onCreate 與 onDestroy,創建和銷毀
    • onStart 與 onStop,顯示與消失
    • onResume 與 onPause,前臺與后臺
  • 舊的活動 onPause,然后新的活動 onResume

1.1.2 異常情況下的生命周期分析

  1. 資源相關的系統配置發生改變導致 Activity 被殺死并重啟(比如橫豎屏切換),這時候會在 onDestroy 前調用 onSaveInstanceState,在 onCreate 后調用 onRestoreInstanceState。要注意兩點問題:
  • 只有在異常情況(包括第二種情況)下 onSaveInstanceState 和 onRestoreInstanceState 才會被調用
  • onRestoreInstanceState 里的 Bundle 參數無需判空,而 onCreate 的 Bundle 參數就需要。
  1. 內存不足導致低優先級的 Activity 被殺死
    指定在某種情況下,系統不會重啟 Activity,可以給 configChanges 屬性添加值,常見的有:
項目 含義
locale 切換了系統語言
orientation 屏幕方向變化
keyboardHidden 鍵盤的可訪問性發生了改變,比如用戶調出了鍵盤
screenSize api 13 以上(min 和 target 大于13)屏幕方向切換不會重啟,否則重啟

1.2 Activity 的啟動模式

1.2.1 Activity 的 LaunchMode

四種啟動模式,解決了一下幾個問題:

  • 單個任務棧下重復創建某個 Activity,創建新的實例還是復用已有的實例
  • Activity 的復用策略,是棧頂復用還是棧內復用
  • 使用 TaskAffinity 屬性配置多任務棧,當任務棧中的一個活動被喚醒,任務棧也恢復到前臺狀態
  1. 標準模式,重新創建目標 Activity,并加入啟動它的 Activity 的任務棧中,所以非 Activity 類型的 Context 啟動標準模式的 Activity 會報錯,這時只要指定 FLAG_ACTIVITY_NEW_TASK 標記位

  2. singleTop,棧頂復用,啟動棧頂的 Activity 不會重新創建,且 onNewIntent 方法會被調用

  3. singleTask,棧內復用

  • 如果要啟動的 Activity 需要的任務棧(根據 TaskAffinity 屬性查找)沒有找到,系統會為它創建該任務棧,并將 Activity 放到棧中
  • 如果需要的任務棧存在,且存在該 Activity 的實例,則該 Activity 不會重新創建,且 onNewIntent 方法會被調用; 如果所需的棧中存在該 Activity,可以指定 FLAG_ACTIVITY_CLEAR_TOP 標記位,則該 Activity 上的 Activity 全部出棧。
  • 單獨講講 TaskAffinity 屬性,它標識了一個 Activity 所需要的任務棧的名字,默認(即不配置該屬性的話)為應用的包名,通常與 singleTask 模式或 allowTaskReparenting 屬性搭配使用:
    • 當與 singleTask 模式配對使用時,如前文所述;
    • 當與 allowTaskReparenting 屬性配對使用時,比如當應用 A 啟動了 應用 B 的某個 Activity,若該 Activity 的 allowTaskReparenting 設置為 true,則當應用 B 啟動時,此 Activity 會直接從應用 A 的任務棧轉移到 應用 B 的任務棧中。
  1. singleInstance,單實例模式,啟動時系統直接為其創建新的任務棧(無需配置 TaskAffinity),也就是永遠不會重復創建該活動的實例

使用 adb shell dumpsys activity 命令查看設備的任務棧

1.2.2 啟動 Activity 的 Flags(Intent 的標志位)

通過 intent.setFlags(Intent.FLAG_ACTIVITY_*) 來動態指定啟動模式

標記 作用
FLAG_ACTIVITY_NEW_TASK 使用 singleTask 模式
FLAG_ACTIVITY_SINGLE_TOP 使用 singleTop 模式
FLAG_ACTIVITY_CLEAR_TOP 位于它上面的 Activity 出棧,與 singleTask 搭配使用
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 不保留此Activity 的啟動歷史,等效在 XML 中指定 android:excludeFromRecents="true"

1.3 IntentFilter 的匹配規則

用于 Activity 的隱式啟動,例如你點擊一個 http url,系統會彈出對話框要你選擇使用哪一種瀏覽器;IntentFilter 的過濾信息有 action,category,data。

<activity android:name=".ui.MainActivity">
  <intent-filter>
      <action android:name="**" />
      <category android:name="**" />
      <data 
          android:scheme="**"
          android:host="**"
          android:port="**"
          android:path="**"
          android:pathPattern="**"
          android:pathPrefix="**"
          android:mimeType="**" />
  </intent-filter>
</activity>
  1. action 表示一個 Activity 能干什么
    比如發送,共享,打電話等等;一個 action 表示一個動作,一個 Intent 中會加入若干個 action,表示它要干什么,沒有同時具備這些能力的 activity 會被過濾掉;如果一個 Intent 沒有 action,那沒人知道它要干什么,也就無法匹配這個 Intent。

  2. category 表示一個 Activity 是什么
    比如可以標記一個 Activity 是地圖,瀏覽器,日歷等等;一個 Intent 中不加 category,系統也會給他一個默認的 category,即 category.DEFAULT;其他情況也是與 action 類似的。

  3. data 表示一個 Activity 可以響應那些類型的資源,具體就是 URI;
    別看 data 的屬性那么多,其實可以分為兩個部分,mimeType 和 URI;一個 URI 的結構就是

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

若沒有主動指定 URI,那么默認就是 content 和 file,即本地文件。
例如百度的 APP 會對 www.baidu.com 的鏈接響應,MP3
播放器會對 MP3 格式的文件響應,迅雷下載器會對特定的 URI 響應等等。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容