一. Activity 生命周期和啟動模式

一. activity生命周期

按照慣例槽奕,先上張 Activity 生命周期圖

回答一個問題: Activity是什么桐绒?
Activity表示為具有用戶界面的單一屏幕产捞,可理解為"界面"超埋。正常情況下昙篙,除了Window秘豹、Dialog和Toast携御,我們能見到的界面的確只有Activity。

生命周期

1.1 activity生命周期分析

1.1.1 生命周期概述

  • onCreate ()
    必須實現此回調既绕,該回調在系統(tǒng)創(chuàng)建Activity時被觸發(fā)啄刹。在這個方法中,應該初始化一些基本組件凄贩,例如創(chuàng)建視圖并進行數據綁定等誓军。最重要的是,調用 setContentView() 去加載界面布局資源疲扎。
    另外昵时,當 onCreate () 完成后,接下來的回調永遠是 onStart ()椒丧。

  • onStart ()
    Activity 進入 "已啟動" 狀態(tài)壹甥,并且對用戶可見。但是還沒有出現在前臺壶熏,也不能用戶進行交互句柠,這個回調做了最后的一些準備工作。

  • onResume ()
    可見棒假、出現在前臺溯职、可交互。 系統(tǒng)在Activity開始與用戶進行交互之前調用此回調帽哑。此時谜酒,Activity位于activity堆棧的頂部,并捕獲用戶的所有輸入妻枕。
    onPause () 回調總是跟在 onResume ()之后僻族。

  • onPause ()
    當 activity 失去焦點并進入暫停狀態(tài)時粘驰,系統(tǒng)會調用。 例如鹰贵,當用戶點擊 "后退" 或 "最近" 按鈕時晴氨,會出現此狀態(tài)。
    當系統(tǒng)調用 onPause () 時碉输,從技術上講,Activity仍然是部分可見的亭珍,但通常表示用戶正在離開Activity敷钾,Activity 將很快進入 Stopped 或者 Resumed 狀態(tài)。
    如果用戶期望 UI 更新肄梨,則處于 Paused 狀態(tài)的 Activity 可以繼續(xù)更新 UI阻荒。 例如 導航地圖屏幕或媒體播放器播放,即使它們失去了焦點众羡,用戶也希望他們的 UI 繼續(xù)更新侨赡。
    你不應該在 onPause 里去保存 應用程序或用戶數據,進行網絡調用粱侣,或執(zhí)行數據庫事務等耗重量級操作羊壹。
    一旦 onPause() 執(zhí)行完畢,接下來的回調將 onStop() 或 onResume()齐婴,根據活動進入暫停狀態(tài)以后會發(fā)生什么決定油猫。

  • onStop ()
    當 activity 不再對用戶可見時,系統(tǒng)會調用柠偶。 這可能是因為 activity 被破壞情妖,或者新 activity 正在開始,又或者 一個存在的activity正在進入 Resumed 狀態(tài)并且正在覆蓋已停止的 activity诱担。

如果這個 activity 準備返回和用戶進行交互毡证,則會回調 onRestart()。
如果這個 activity 完全終止蔫仙,則會回調 onDestroy()

  • onRestart ()
    當處于 "Stopped" 狀態(tài)的 activity 即將重新啟動時料睛,系統(tǒng)會調用此方法。 onRestart()會還原 activity 在 stopped時的狀態(tài)數據匀哄。

  • onDestroy ()
    系統(tǒng)在activity 銷毀之前調用此回調秦效。
    此回調是activity 收到的最后一個回調。在這里涎嚼,可以做一些回收工作和最終的資源釋放阱州。

1.1.2 生命周期具體說明

  • 針對一個Activity,第一次啟動法梯,回調如下:onCreate -> onStart -> onResume苔货。

  • 當用戶打開新的 activity 或者切換到桌面 或者按最近按鈕時犀概,回調如下:onPause -> onStop。
    特殊情況, 如果新Activity采用透明主題時夜惭,回調如下:onPause姻灶。

  • 當用戶再次回到原 activity 時,回調如下:onRestart -> onStart -> onResume诈茧。

  • 當用戶彈出一個對話框( AlertDialog )時产喉,activity 生命周期不會發(fā)生變化。

  • 當用戶按back回退時敢会,回調如下:onPause -> onStop ->onDestroy曾沈。

問題:當前Activity 為A, 此時用戶打開一個新的Activity B鸥昏,那么 B 的 onResume 和 A 的 onPause 哪個先執(zhí)行?

  1. 可自己動手試一試塞俱,答案是 舊 Activity A 先 onPause,然后 新 Activity B 再啟動吏垮。其實很好理解障涯,onResume代表著可見、可交互膳汪,如果舊的 Activity 不先 onPause唯蝶,那豈不是會出現兩個可見、可交互的界面旅敷,不就亂套了生棍。
  2. 看源碼更能加深理解。

1.2 activity狀態(tài)

只有三個狀態(tài)是靜態(tài)的媳谁,可以存在較長時間保持狀態(tài)不變涂滴。(其他狀態(tài)只是過渡狀態(tài),系統(tǒng)快速切換并切換到下一狀態(tài))

  • 運行(Resumed)

    • 當前 activity 處于棧頂晴音,用戶可以與它進行交互柔纵。(通常也被理解為 "running" 狀態(tài))
    • 此狀態(tài)由 onResume() 進入,onPause() 退出
  • 暫停(Paused)

    • 當前 activity 仍然是可見的锤躁,但被另一個 activity 處在最上方搁料,最上方的 activity 是半透明的,或者是部分覆蓋整個屏幕系羞。被暫停的 activity 不會再接收用戶的輸入郭计。
    • 處于活著的狀態(tài) (Activity 對象存留在內存,保持著所有的 狀態(tài)和成員信息椒振,仍然吸附在 window manager)昭伸。
    • 當資源內存極度不足時,系統(tǒng)會殺掉該 activity 釋放相應資源澎迎。
    • 此狀態(tài)由 onPaues() 進入庐杨,退出可能是從 onResume() 重新喚醒軟件选调,或者被 onStop() 殺掉。
  • 停止(Stopped)

    • 當前 activity 完全被隱藏灵份,不被用戶可見仁堪,可以認為是處于后臺。
    • 處于活著的狀態(tài) (Activity 對象存留在內存填渠,保持著所有的 狀態(tài)和成員信息弦聂,不再吸附在 window manager)。
    • 由于對用戶不再可見氛什,只要有內存的需要横浑,系統(tǒng)會殺掉該 activity 來釋放相應資源。
    • 此狀態(tài)由 onStop() 進入屉更,退出是從 onRestart() 重新喚醒軟件,或者被 onDestroy() 徹底死亡洒缀。其他狀態(tài)(Created與 Started )都是短暫的瑰谜,系統(tǒng)快速執(zhí)行那些回調函數并通過。

1.3 android進程優(yōu)先級

  • 前臺進程
    一般情況是树绩,在前臺與用戶進行交互的 activity萨脑,或與前臺進程 綁定的 service。

  • 可見進程
    處于 paused 狀態(tài)饺饭,用戶可見渤早,但是不能進行交互。

  • 服務進程
    如果一個進程中運行著 service瘫俊,這個service 是通過 startService() 開啟的鹊杖,并且不屬于上面兩種高優(yōu)先級的情況,那它就是一個服務進程扛芽。

  • 后臺進程
    處于 stopped 狀態(tài)骂蓖。

  • 空進程
    如果一個進程不包含任何活躍的應用組件,則認為是空進程川尖。

二. android任務棧

任務棧是一種“后進先出”的棧結構登下。
任務棧分為 前臺任務棧后臺任務棧 ,后臺任務棧中的 activity 位于暫停狀態(tài)叮喳。

  • TaskAffinity 任務相關性被芳, 這個參數標識了一個 Activity 所需要的任務棧的名字。
  • 默認情況下馍悟,所有 Activity 所需的任務棧的名字為包名畔濒。
  • 通過指定 TaskAffinity 可以為 Activity 指定新的任務棧的名字,當然必須不能和包名相同赋朦。
  • TaskAfiinity 主要是和 singleTask 啟動模式或者 allowTaskReparenting 屬性配對使用篓冲。
  • 在 AndroidManifest 文件中指定李破。
  • 命令** adb shell dumpsys activity** 可導出 Activity 信息。

三. activity啟動模式

  • standard(標準模式)
    系統(tǒng)默認模式壹将,每啟動一個 Activity 就會重新創(chuàng)建一個新的實例嗤攻。
    這種模式下, Activity A 啟動了 Activity B诽俯,那么 B 就會進入到 A 所在的任務棧中妇菱。

  • singleTop(棧頂復用模式)
    如果新 Activity 已經位于棧頂,那么此 Activity 不會再重新創(chuàng)建暴区,同時它的 onNewIntent 方法會被回調闯团。

  • singleTask(棧內復用模式)
    只要 Activity 在一個棧中存在,那么多次啟動此 Activity 都不會重新創(chuàng)建實例仙粱。

  • singleInstance(單實例模式, 加強的 singleTask 模式)
    除了具有 singleTask 模式的所有特性外房交,還加強了一點,那就是具有此種模式的 Activity 只能單獨的位于一個任務棧中伐割。

例1:
任務棧(com.yjnull.slowdev4android)有個 ExampleActivity 候味,啟動模式為standard。
任務棧(com.yy.task1)有個 ThreeActivity隔心,啟動模式為 singleInstance白群。
啟動ExampleActivity,然后啟動ThreeActivity硬霍,然后兩個互相啟動帜慢,任務棧如下截圖。

activity_task1.png

例2:

啟動模式

四. IntentFilter 的匹配規(guī)則

隱式啟動 Activity 需要 Intent 能夠匹配目標組件的 IntentFilter中所設置的過濾信息唯卖,如果不匹配則無法啟動目標組件粱玲。
IntentFilter 的過濾信息有 action、category耐床、data

  • action:
    1.action是一個字符串 區(qū)分大小寫
    2.當過濾規(guī)則中有 action 時密幔,那么只要 Intent 中的 action 能夠和過濾規(guī)則中的任何一個相同即可匹配成功。需注意:如果Intent 沒有指定 action撩轰,將匹配失敗胯甩。
    3.也就是說,當過濾規(guī)則有 action 時堪嫂,Intent 中必須存在 action偎箫。

  • category:
    1.category 和 action 不同,它不強制要求 Intent 中必須含有 category皆串。
    2.如果 Intent 中沒有 category淹办,那么可以匹配成功。
    3.如果 Intent 中有 category恶复,那么不管有幾個 category怜森,都必須和過濾規(guī)則中的 category 相同才能匹配成功速挑。
    4.為什么不設置 category 也可以匹配成功,因為 startActivity 時會默認為 Intent 加上 "android.intent.category.DEFAULT" 這個 category副硅。
    5.所以為了 activity 能夠接收隱式調用姥宝,必須在intent-filter 中指定 "android.intent.category.DEFAULT" 這個 category。

  • data
    1.data 由兩部分組成:mimeType 和 URI恐疲。
    2.mimeType 指媒體類型:如 image/jpeg腊满、video/*等。
    3.URI 結構:
    <schema>://<host>:<port>/[<path>|<pathPrefit>|<pathPattern>]
    4.如果沒有指定 URI 培己,則 URI 的默認值為 content 或 file
    5.例如指定 mimeType 為 image/png碳蛋,未指定 URI 。 則如下代碼可匹配過濾規(guī)則
    intent.setDataAndType(Uri.parse("file://abc"), "image/png");
    或者
    intent.setDataAndType(Uri.parse("content://abc"), "image/png");

  • 總結
    1.隱式啟動 Activity 時省咨,IntentFilter 一定要指定 "android.intent.category.DEFAULT" 這個 category肃弟。
    2.action、category零蓉、data ,如果匹配了 action愕乎,那么其余兩個也得匹配成功才能找到 Activity。
    3.如果只匹配 data壁公,那么 action 不指定也可以運行成功,不會返回指定 Activity绅项,而是返回ResolverActivity紊册,讓你選擇默認程序運行。

參考

http://gityuan.com/
Android 開發(fā)藝術探索

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末快耿,一起剝皮案震驚了整個濱河市囊陡,隨后出現的幾起案子,更是在濱河造成了極大的恐慌掀亥,老刑警劉巖撞反,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異搪花,居然都是意外死亡遏片,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門撮竿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吮便,“玉大人,你說我怎么就攤上這事幢踏∷栊瑁” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵房蝉,是天一觀的道長僚匆。 經常有香客問我微渠,道長,這世上最難降的妖魔是什么咧擂? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任逞盆,我火速辦了婚禮,結果婚禮上屋确,老公的妹妹穿的比我還像新娘纳击。我一直安慰自己,他們只是感情好攻臀,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布焕数。 她就那樣靜靜地躺著,像睡著了一般刨啸。 火紅的嫁衣襯著肌膚如雪堡赔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天设联,我揣著相機與錄音善已,去河邊找鬼。 笑死离例,一個胖子當著我的面吹牛换团,可吹牛的內容都是我干的。 我是一名探鬼主播宫蛆,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼艘包,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耀盗?” 一聲冷哼從身側響起想虎,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叛拷,沒想到半個月后舌厨,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡忿薇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年裙椭,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片署浩。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡骇陈,死狀恐怖,靈堂內的尸體忽然破棺而出瑰抵,到底是詐尸還是另有隱情你雌,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站婿崭,受9級特大地震影響拨拓,放射性物質發(fā)生泄漏。R本人自食惡果不足惜氓栈,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一渣磷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧授瘦,春花似錦醋界、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至徒欣,卻和暖如春逐样,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背打肝。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工脂新, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粗梭。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓争便,卻偏偏與公主長得像,于是被迫代替她去往敵國和親断医。 傳聞我的和親對象是個殘疾皇子始花,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內容