Activity 的 36 大難點(diǎn)爽待,你會(huì)幾個(gè)损同?「建議收藏」

Android

前言

  • 學(xué) Android 有一段時(shí)間了,一直都只顧著學(xué)新的東西鸟款,最近發(fā)現(xiàn)很多平常用的少的東西竟讓都忘了膏燃,趁著這兩天,打算把有關(guān) Activity 的內(nèi)容以問(wèn)題的形式梳理出來(lái)何什,也供大家查缺補(bǔ)漏组哩。

本文中,我將一改往日寫博客的習(xí)慣富俄,全文用 XMind 將所有知識(shí)點(diǎn)以思維導(dǎo)圖的形式呈現(xiàn)禁炒,歡迎大家食用~~

文章目錄


文章目錄

方便大家學(xué)習(xí),我在 GitHub 上建立個(gè) 倉(cāng)庫(kù)


神圖


  • 在開(kāi)始之前,先讓我們看看 Androidactivity 到底都有哪些東西康辑?
  • 借一張網(wǎng)上很火的圖帶你了解 Activity
一張圖帶你了解 Activity

一摄欲、 生命周期


  • 先貼一張聞名遐邇的圖
  • 我們生命周期先看看具體有哪些方法回調(diào),在逐一攻破:

[圖片上傳失敗...(image-76615c-1572405738902)]

1.1 Dialog 彈出時(shí)

dialog彈出時(shí)
  • 如果是單純是創(chuàng)建的 dialog 疮薇,Activity 并不會(huì)執(zhí)行生命周期的方法
  • 但是如果是跳轉(zhuǎn)到一個(gè)不是全屏的 Activity 的話, 當(dāng)然就是按照正常的生命周期來(lái)執(zhí)行了
  • onPasue() -> onPause() ( 不會(huì)執(zhí)行原 ActivityonStop() , 否則上個(gè)頁(yè)面就不顯示了 )

1.2 橫豎屏切換時(shí)

橫豎屏切換時(shí)
  • 不設(shè)置 Activityandroid:configChanges 時(shí)胸墙,切屏?xí)匦抡{(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次按咒,切豎屏?xí)r會(huì)執(zhí)行兩次

  • 設(shè)置 Activityandroid:configChanges="orientation" 時(shí)迟隅,切屏還是會(huì)重新調(diào)用各個(gè)生命周期,切橫励七、豎屏?xí)r只會(huì)執(zhí)行一次

  • 設(shè)置 Activityandroid:configChanges="orientation|keyboardHidden" 時(shí)智袭,切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行 onConfigurationChanged 方法

  • 注意:還有一點(diǎn)掠抬,非常重要补履,一個(gè) Android 的變更細(xì)節(jié)!當(dāng) API >12 時(shí)剿另,需要加入 screenSize 屬性箫锤,否則屏幕切換時(shí)即使你設(shè)置了 orientation 系統(tǒng)也會(huì)重建 Activity 贬蛙!

  • 橫豎屏切換生命周期的執(zhí)行

1.3 不同場(chǎng)景下 Activity 生命周期的變化過(guò)程

不同場(chǎng)景下Activity生命周期的變化過(guò)程
  • 啟動(dòng) ActivityonCreate() ---> onStart() ---> onResume()Activity 進(jìn)入運(yùn)行狀態(tài)谚攒。
  • 鎖屏?xí)r會(huì)執(zhí)行 onPause()onStop() , 而開(kāi)屏?xí)r則應(yīng)該執(zhí)行 onStart() onResume()
已啟動(dòng)的 Activity 生命周期的變化
  • Activity 退居后臺(tái): 當(dāng)前 Activity 轉(zhuǎn)到新的 Activity 界面或按 Home 鍵回到主屏: onPause() ---> onStop() 阳准,進(jìn)入停滯狀態(tài)。
  • Activity 返回前臺(tái): onRestart() ---> onStart() ---> onResume() 馏臭,再次回到運(yùn)行狀態(tài)野蝇。
  • Activity 退居后臺(tái): 且系統(tǒng)內(nèi)存不足, 系統(tǒng)會(huì)殺死這個(gè)后臺(tái)狀態(tài)的 Activity 括儒,若再次回到這個(gè) Activity ,則會(huì)走 onCreate() --> onStart() ---> onResume()

1.4 將一個(gè) Activity 設(shè)置成窗口的樣式

設(shè)置 Activity 成窗口樣式

只需要給我們的 Activity 配置如下屬性即可绕沈。
android:theme="@android:style/Theme.Dialog"

1.5 退出已調(diào)用多個(gè) Activity 的 Application

  • 通常情況用戶退出一個(gè) Activity 只需按返回鍵,我們寫代碼想退出 activity 直接調(diào)用 finish() 方法就行固逗。
退出調(diào)用多個(gè) Activity 的 Application
  • 發(fā)送特定廣播:
  1. 在需要結(jié)束應(yīng)用時(shí), 發(fā)送一個(gè)特定的廣播,每個(gè) Activity 收到廣播后,關(guān)閉 即可哈踱。
  2. 給某個(gè) activity 注冊(cè)接受接受廣播的意圖 registerReceiver(receiver, filter)
  3. 如果過(guò)接受到的是 關(guān)閉 activity 的廣播 activity finish()
  • 遞歸退出
  1. 就調(diào)用 finish() 方法 把當(dāng)前的 Activity 退出
  2. 在打開(kāi)新的 Activity 時(shí)使用 startActivityForResult , 然后自己加標(biāo)志, 在 onActivityResult 中處理, 遞歸關(guān)閉。
  • 其實(shí)
  1. 也可以通過(guò) intentflag 來(lái)實(shí)現(xiàn) intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 激活一個(gè)新的 activity奋早。
  2. 此時(shí)如果該任務(wù)棧中已經(jīng)有該 Activity , 那么系統(tǒng)會(huì)把這個(gè) Activity 上面的所有 Activity 干掉姓建。
  3. 其實(shí)相當(dāng)于給 Activity 配置的啟動(dòng)模式為 singleTask 屑柔。
  • 記錄打開(kāi)的 Activity
  1. 每打開(kāi)一個(gè) Activity , 就記錄下來(lái)。
  2. 在需要退出時(shí) , 關(guān)閉每一個(gè) Activity

1.6 鎖定屏與解鎖屏幕塌衰,Activity 如何執(zhí)行生命周期

鎖定屏與解鎖屏幕仍源,Activity如何執(zhí)行生命周期
  • 鎖屏?xí)r會(huì)執(zhí)行 onPause()onStop() , 而開(kāi)屏?xí)r則應(yīng)該執(zhí)行 onStart() onResume()

1.7 修改 Activity 進(jìn)入和退出動(dòng)畫(huà)

修改 Activity 進(jìn)入和退出動(dòng)畫(huà)
  • 可以通過(guò)兩種方式 圃郊, 一是通過(guò)定義 Activity 的主題 价涝,二是通過(guò)覆寫 ActivityoverridePendingTransition 方法。
  • 通過(guò)設(shè)置主題樣式在 styles.xml 中編輯代碼 , 添加 themes.xml 文件:在 AndroidManifest.xml 中給指定的 Activity 指定 theme持舆。
  • 覆寫 overridePendingTransition 方法:overridePendingTransition(R.anim.fade, R.anim.hold);

1.8 Activity 的四種狀態(tài)

四種狀態(tài)
  • runnig :用戶可以點(diǎn)擊色瘩,activity 處于棧頂狀態(tài)。
  • pausedactivity 失去焦點(diǎn)的時(shí)候逸寓,被一個(gè)非全屏的 activity 占據(jù)或者被一個(gè)透明的 activity 覆蓋居兆,這個(gè)狀態(tài)的 activity 并沒(méi)有銷毀,它所有的狀態(tài)信息和成員變量仍然存在竹伸,只是不能夠被點(diǎn)擊泥栖。(內(nèi)存緊張的情況,這個(gè) activity 有可能被回收)
關(guān)閉
  • stopped :這個(gè) activity 被另外一個(gè) activity 完全覆蓋勋篓,但是這個(gè) activity 的所有狀態(tài)信息和成員變量仍然存在(除了內(nèi)存緊張)
  • killed :這個(gè) activity 已經(jīng)被銷毀吧享,其所有的狀態(tài)信息和成員變量已經(jīng)不存在了栏账。

1.9 如何處理異常退出

如何處理異常退出
  • Activity 異常退出的時(shí)候 --> onPause() --> onSaveInstanceState() --> onStop() --> onDestory()
  • 需要注意的是 onSaveInstanceState() 方法與 onPause 并沒(méi)有嚴(yán)格的先后關(guān)系抢肛,有可能在 onPause 之前术陶,也有可能在其后面調(diào)用健田,但會(huì)在 onStop() 方法之前調(diào)用
  • 異常退出后又重新啟動(dòng)該 Activity --> onCreate() --> onStart() --> onRestoreInstanceState() --> onResume()
異常退出后又重新啟動(dòng)
  • 搞懂這個(gè)生命周期的執(zhí)行后就可以回答了,首先要知道面試官的意思:是要重新啟動(dòng)并恢復(fù)這個(gè) Activity 還是說(shuō)直接退出整個(gè) app
  • 如果要恢復(fù)則要在 onSaveInstanceState() 中進(jìn)行保存數(shù)據(jù)并在 onRestoreInstanceState() 中進(jìn)行恢復(fù)
  • 如果是要退出 app 的話就要捕獲全局的異常信息柿扣,并退出 app
  • 當(dāng)然個(gè)人建議是使用 UncaughtExceotionHandler 來(lái)捕獲全局異常進(jìn)行退出 app 的操作钠至,這樣會(huì)減少之前崩潰所造成的后遺癥近哟!

1.10 什么是 onNewIntent

onNewIntent
  • 如果 IntentActivity 處于任務(wù)棧的頂端盐股,也就是說(shuō)之前打開(kāi)過(guò)的 Activity 钱豁,現(xiàn)在處于 onPause 耻卡、 onStop 狀態(tài)的話疯汁,其他應(yīng)用再發(fā)送 Intent 的話

  • 執(zhí)行順序?yàn)椋?code>onNewIntent,onRestart卵酪,onStart幌蚊,onResume谤碳。

二、 啟動(dòng)模式


2.1 啟動(dòng)模式

啟動(dòng)模式
  • Activity 一共有四種 launchModestandard 溢豆、singleTop 蜒简、singleTasksingleInstance 漩仙。
Standard
  • Standard 模式(默認(rèn)模式)
  1. 說(shuō)明: 每次啟動(dòng)一個(gè) Activity 都會(huì)又一次創(chuàng)建一個(gè)新的實(shí)例入棧搓茬,無(wú)論這個(gè)實(shí)例是否存在。

  2. 生命周期:每次被創(chuàng)建的實(shí)例 Activity 的生命周期符合典型情況队他,它的 onCreate 卷仑、onStartonResume 都會(huì)被調(diào)用麸折。

  3. 舉例:此時(shí) Activity 棧中以此有 A 锡凝、BC 三個(gè) Activity 垢啼,此時(shí)C處于棧頂窜锯,啟動(dòng)模式為 Standard 模式。若在 C Activity 中加入點(diǎn)擊事件芭析,須要跳轉(zhuǎn)到還有一個(gè)同類型的 C Activity 锚扎。結(jié)果是還有一個(gè) C Activity 進(jìn)入棧中,成為棧頂放刨。

SingleTop
  • SingleTop 模式(棧頂復(fù)用模式)
  1. 說(shuō)明:分兩種處理情況:須要?jiǎng)?chuàng)建的 Activity 已經(jīng)處于棧頂時(shí)工秩,此時(shí)會(huì)直接復(fù)用棧頂?shù)?Activity 。不會(huì)再創(chuàng)建新的 Activity 进统;若須要?jiǎng)?chuàng)建的 Activity 不處于棧頂助币,此時(shí)會(huì)又一次創(chuàng)建一個(gè)新的 Activity 入棧,同 Standard 模式一樣螟碎。

  2. 生命周期:若情況一中棧頂?shù)?Activity 被直接復(fù)用時(shí)眉菱,它的 onCreateonStart 不會(huì)被系統(tǒng)調(diào)用掉分,由于它并沒(méi)有發(fā)生改變俭缓。可是一個(gè)新的方法 onNewIntent 會(huì)被回調(diào)( Activity 被正常創(chuàng)建時(shí)不會(huì)回調(diào)此方法)酥郭。

  3. 舉例:此時(shí) Activity 棧中以此有 A 华坦、BC 三個(gè) Activity 不从,此時(shí) C 處于棧頂惜姐,啟動(dòng)模式為 SingleTop 模式。情況一:在 C Activity 中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)同類型的 C Activity 歹袁。結(jié)果是直接復(fù)用棧頂?shù)?C Activity坷衍。情況二:在 C Activity 中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè) A Activity条舔。結(jié)果是創(chuàng)建一個(gè)新的 Activity 入棧枫耳。成為棧頂。

SingleTask
  • SingleTask 模式(棧內(nèi)復(fù)用模式)
  1. 說(shuō)明:若須要?jiǎng)?chuàng)建的 Activity 已經(jīng)處于棧中時(shí)孟抗,此時(shí)不會(huì)創(chuàng)建新的 Activity 迁杨,而是將存在棧中的 Activity 上面的其他 Activity 所有銷毀,使它成為棧頂凄硼。

  2. 如果是在別的應(yīng)用程序中啟動(dòng)它仑最,則會(huì)新建一個(gè) task ,并在該task中啟動(dòng)這個(gè) Activity 帆喇,singleTask 允許別的 Activity 與其在一個(gè) task 中共存警医,也就是說(shuō),如果我在這個(gè) singleTask 的實(shí)例中再打開(kāi)新的 Activity 坯钦,這個(gè)新的 Activity 還是會(huì)在 singleTask 的實(shí)例的 task 中预皇。

  3. 生命周期:同 SingleTop 模式中的情況一同樣。僅僅會(huì)又一次回調(diào) Activity 中的 onNewIntent 方法

  4. 舉例:此時(shí) Activity 棧中以此有 A 婉刀、B 吟温、C 三個(gè) Activity 。此時(shí) C 處于棧頂突颊,啟動(dòng)模式為 SingleTask 模式鲁豪。情況一:在 C Activity 中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)同類型的 C Activity 律秃。結(jié)果是直接用棧頂?shù)?C Activity 爬橡。情況二:在 C Activity 中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè) A Activity 棒动。結(jié)果是將 A Activity 上面的 B 糙申、C 所有銷毀,使 A Activity 成為棧頂船惨。

ingleInstance
  • SingleInstance 模式(單實(shí)例模式)
  1. 說(shuō)明: SingleInstance 比較特殊柜裸,是全局單例模式,是一種加強(qiáng)的 SingleTask 模式粱锐。它除了具有它所有特性外疙挺,還加強(qiáng)了一點(diǎn):只有一個(gè)實(shí)例,并且這個(gè)實(shí)例獨(dú)立運(yùn)行在一個(gè) task 中怜浅,這個(gè) task 只有這個(gè)實(shí)例铐然,不允許有別的 Activity 存在。

  2. 這個(gè)經(jīng)常使用于系統(tǒng)中的應(yīng)用,比如 Launch 锦爵、鎖屏鍵的應(yīng)用等等,整個(gè)系統(tǒng)中僅僅有一個(gè)奥裸!所以在我們的應(yīng)用中一般不會(huì)用到险掀。了解就可以。

  3. 舉例:比方 A Activity 是該模式湾宙,啟動(dòng) A 后樟氢。系統(tǒng)會(huì)為它創(chuàng)建一個(gè)單獨(dú)的任務(wù)棧,由于棧內(nèi)復(fù)用的特性侠鳄。興許的請(qǐng)求均不會(huì)創(chuàng)建新的 Activity 埠啃,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀。

2.2 啟動(dòng)模式的使用方式

啟動(dòng)模式的使用方式
  • Manifest.xml 中指定 Activity 啟動(dòng)模式
  1. 一種靜態(tài)的指定方法
  2. Manifest.xml 文件里聲明 Activity 的同一時(shí)候指定它的啟動(dòng)模式
  3. 這樣在代碼中跳轉(zhuǎn)時(shí)會(huì)依照指定的模式來(lái)創(chuàng)建 Activity 伟恶。
  • 啟動(dòng) Activity 時(shí)碴开。在 Intent 中指定啟動(dòng)模式去創(chuàng)建 Activity
  1. 一種動(dòng)態(tài)的啟動(dòng)模式
  2. new 一個(gè) Intent
  3. 通過(guò) IntentaddFlags 方法去動(dòng)態(tài)指定一個(gè)啟動(dòng)模式。
  • 注意:以上兩種方式都能夠?yàn)?Activity 指定啟動(dòng)模式博秫,可是二者還是有差別的潦牛。
  1. 優(yōu)先級(jí):動(dòng)態(tài)指定方式即另外一種比第一種優(yōu)先級(jí)要高,若兩者同一時(shí)候存在挡育,以另外一種方式為準(zhǔn)巴碗。

  2. 限定范圍:第一種方式無(wú)法為 Activity 直接指定 FLAG_ACTIVITY_CLEAR_TOP 標(biāo)識(shí),另外一種方式無(wú)法為 Activity 指定 singleInstance 模式即寒。

2.3 啟動(dòng)模式的實(shí)際應(yīng)用場(chǎng)景

這四種模式中的 Standard 模式是最普通的一種橡淆,沒(méi)有什么特別注意。而 SingleInstance 模式是整個(gè)系統(tǒng)的單例模式母赵,在我們的應(yīng)用中一般不會(huì)應(yīng)用到逸爵。所以,這里就具體解說(shuō) SingleTopSingleTask 模式的運(yùn)用場(chǎng)景:

啟動(dòng)模式的實(shí)際應(yīng)用場(chǎng)景
  • SingleTask 模式的運(yùn)用場(chǎng)景
  1. 最常見(jiàn)的應(yīng)用場(chǎng)景就是保持我們應(yīng)用開(kāi)啟后僅僅有一個(gè) Activity 的實(shí)例凹嘲。
  2. 最典型的樣例就是應(yīng)用中展示的主頁(yè)( Home 頁(yè))痊银。
  3. 假設(shè)用戶在主頁(yè)跳轉(zhuǎn)到其他頁(yè)面,運(yùn)行多次操作后想返回到主頁(yè)施绎,假設(shè)不使用 SingleTask 模式溯革,在點(diǎn)擊返回的過(guò)程中會(huì)多次看到主頁(yè),這明顯就是設(shè)計(jì)不合理了谷醉。
  • SingleTop 模式的運(yùn)用場(chǎng)景
  1. 假設(shè)你在當(dāng)前的 Activity 中又要啟動(dòng)同類型的 Activity
  2. 此時(shí)建議將此類型 Activity 的啟動(dòng)模式指定為 SingleTop 致稀,能夠降低Activity的創(chuàng)建,節(jié)省內(nèi)存俱尼!
  • 注意:復(fù)用 Activity 時(shí)的生命周期回調(diào)
  1. 這里還須要考慮一個(gè) Activity 跳轉(zhuǎn)時(shí)攜帶頁(yè)面參數(shù)的問(wèn)題抖单。
  2. 由于當(dāng)一個(gè) Activity 設(shè)置了 SingleTop 或者 SingleTask 模式后,跳轉(zhuǎn)此 Activity 出現(xiàn)復(fù)用原有 Activity 的情況時(shí),此 ActivityonCreate 方法將不會(huì)再次運(yùn)行矛绘。onCreate 方法僅僅會(huì)在第一次創(chuàng)建 Activity 時(shí)被運(yùn)行耍休。
  3. 而一般 onCreate 方法中會(huì)進(jìn)行該頁(yè)面的數(shù)據(jù)初始化、UI 初始化货矮,假設(shè)頁(yè)面的展示數(shù)據(jù)無(wú)關(guān)頁(yè)面跳轉(zhuǎn)傳遞的參數(shù)羊精,則不必操心此問(wèn)題
  4. 若頁(yè)面展示的數(shù)據(jù)就是通過(guò) getInten() 方法來(lái)獲取,那么問(wèn)題就會(huì)出現(xiàn):getInten() 獲取的一直都是老數(shù)據(jù)囚玫,根本無(wú)法接收跳轉(zhuǎn)時(shí)傳送的新數(shù)據(jù)喧锦!
  • 以下,通過(guò)一個(gè)樣例來(lái)具體解釋:
圖片描述
  • 以上代碼中的 CourseDetailActivity 在配置文件里設(shè)置了啟動(dòng)模式是 SingleTop 模式抓督,依據(jù)上面啟動(dòng)模式的介紹可得知燃少,當(dāng) CourseDetailActivity 處于棧頂時(shí)。

  • 再次跳轉(zhuǎn)頁(yè)面到 CourseDetailActivity 時(shí)會(huì)直接復(fù)用原有的 Activity 铃在,并且此頁(yè)面須要展示的數(shù)據(jù)是從 getIntent() 方法得來(lái)阵具,可是 initData() 方法不會(huì)再次被調(diào)用,此時(shí)頁(yè)面就無(wú)法顯示新的數(shù)據(jù)定铜。

  • 當(dāng)然這樣的情況系統(tǒng)早就為我們想過(guò)了怔昨,這時(shí)我們須要另外一個(gè)回調(diào) onNewIntent(Intent intent)方法。此方法會(huì)傳入最新的 intent 宿稀,這樣我們就能夠解決上述問(wèn)題趁舀。這里建議的方法是又一次去 setIntent 。然后又一次去初始化數(shù)據(jù)和 UI 祝沸。代碼例如以下所看到的:

圖片描述
  • 這樣矮烹,在一個(gè)頁(yè)面中能夠反復(fù)跳轉(zhuǎn)并顯示不同的內(nèi)容。

2.4 快速啟動(dòng)一個(gè) Activity

快速啟動(dòng)一個(gè) Activity
  • 這個(gè)問(wèn)題其實(shí)也是比較簡(jiǎn)單的罩锐,就是不要在 ActivityonCreate 方法中執(zhí)行過(guò)多繁重的操作奉狈,并且在 onPasue 方法中同樣不能做過(guò)多的耗時(shí)操作。

2.5 啟動(dòng)流程

2.6 Activity 的 Flags

Activity 的 Flags
  • 標(biāo)記位既能夠設(shè)定Activity的啟動(dòng)模式,如同上面介紹的竭恬,在動(dòng)態(tài)指定啟動(dòng)模式跛蛋,比方 FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_SINGLE_TOP 等。它還能夠影響 Activity 的運(yùn)行狀態(tài) 痊硕,比方 FLAG_ACTIVITY_CLEAN_TOPFLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 等赊级。

  • 以下介紹幾個(gè)基本的標(biāo)記位,切勿死記岔绸,理解幾個(gè)就可以理逊,須要時(shí)再查官方文檔橡伞。

幾個(gè)基本的標(biāo)記位
  • FLAG_ACTIVITY_NEW_TASK
  1. 作用是為 Activity 指定 “SingleTask” 啟動(dòng)模式。跟在 AndroidMainfest.xml 指定效果同樣
  • FLAG_ACTIVITY_SINGLE_TOP
  1. 作用是為 Activity 指定 “SingleTop” 啟動(dòng)模式晋被,跟在 AndroidMainfest.xml 指定效果同樣兑徘。
  • FLAG_ACTIVITY_CLEAN_TOP
  1. 具有此標(biāo)記位的 Activity ,啟動(dòng)時(shí)會(huì)將與該 Activity 在同一任務(wù)棧的其他 Activity 出棧羡洛。
  2. 一般與 SingleTask 啟動(dòng)模式一起出現(xiàn)挂脑。
  3. 它會(huì)完畢 SingleTask 的作用。
  4. 但事實(shí)上 SingleTask 啟動(dòng)模式默認(rèn)具有此標(biāo)記位的作用
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
  1. 具有此標(biāo)記位的 Activity 不會(huì)出如今歷史 Activity 的列表中
  2. 使用場(chǎng)景:當(dāng)某些情況下我們不希望用戶通過(guò)歷史列表回到 Activity 時(shí)翘县,此標(biāo)記位便體現(xiàn)了它的效果。
  3. 它等同于在 xml 中指定 Activity 的屬性.

2.7 onNewInstent()方法什么時(shí)候執(zhí)行

onNewInstent()方法什么時(shí)候執(zhí)行

這個(gè)是啟動(dòng)模式中的了谴分,當(dāng)此 Activity 的實(shí)例已經(jīng)存在锈麸,并且此時(shí)的啟動(dòng)模式為 SingleTaskSingleInstance ,另外當(dāng)這個(gè)實(shí)例位于棧頂且啟動(dòng)模式為 SingleTop 時(shí)也會(huì)觸發(fā) onNewInstent() 牺蹄。

三忘伞、 數(shù)據(jù)


3.1 Activity 間通過(guò) Intent 傳遞數(shù)據(jù)大小限制

Activity 間通過(guò) Intent 傳遞數(shù)據(jù)大小限制
  • Intent 在傳遞數(shù)據(jù)時(shí)是有大小限制的,這里官方并未詳細(xì)說(shuō)明沙兰,不過(guò)通過(guò)實(shí)驗(yàn)的方法可以測(cè)出數(shù)據(jù)應(yīng)該被限制在 1MB 之內(nèi)( 1024KB
  • 我們采用傳遞 Bitmap 的方法氓奈,發(fā)現(xiàn)當(dāng)圖片大小超過(guò) 1024(準(zhǔn)確地說(shuō)是 1020 左右)的時(shí)候,程序就會(huì)出現(xiàn)閃退鼎天、停止運(yùn)行等異常(不同的手機(jī)反應(yīng)不同)
  • 因此可以判斷 Intent 的傳輸容量在 1MB 之內(nèi)舀奶。

3.2 內(nèi)存不足時(shí)系統(tǒng)會(huì)殺掉后臺(tái)的Activity,若需要進(jìn)行一些臨時(shí)狀態(tài)的保存斋射,在哪個(gè)方法進(jìn)行

onSaveInstanceState()
  • ActivityonSaveInstanceState()onRestoreInstanceState() 并不是生命周期方法育勺,它們不同于 onCreate()onPause() 等生命周期方法罗岖,它們并不一定會(huì)被觸發(fā)涧至。

  • onSaveInstanceState() 方法,當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足桑包、用戶直接按 Home 鍵)由系統(tǒng)銷毀一個(gè) Activity 南蓬,onSaveInstanceState() 會(huì)被調(diào)用。

  • 但是當(dāng)用戶主動(dòng)去銷毀一個(gè) Activity 時(shí)哑了,例如在應(yīng)用中按返回鍵赘方,onSaveInstanceState() 就不會(huì)被調(diào)用。

  • 除非該 activity 不是被用戶主動(dòng)銷毀的弱左,通常 onSaveInstanceState() 只適合用于保存一些臨時(shí)性的狀態(tài)蒜焊,而 onPause() 適合用于數(shù)據(jù)的持久化保存。

3.3 onSaveInstanceState() 被執(zhí)行的場(chǎng)景

onSaveInstanceState() 被執(zhí)行的場(chǎng)景
  • 系統(tǒng)不知道你按下 HOME 后要運(yùn)行多少其他的程序科贬,自然也不知道 activity A 是否會(huì)被銷毀
  • 因此系統(tǒng)都會(huì)調(diào)用 onSaveInstanceState() 泳梆,讓用戶有機(jī)會(huì)保存某些非永久性的數(shù)據(jù)鳖悠。以下幾種情況的分析都遵循該原則:
  1. 當(dāng)用戶按下 HOME 鍵時(shí)
  2. 長(zhǎng)按 HOME 鍵,選擇運(yùn)行其他的程序時(shí)
  3. 鎖屏?xí)r
  4. activity A 中啟動(dòng)一個(gè)新的 activity 時(shí)
  5. 屏幕方向切換時(shí)

3.4 兩個(gè) Activity 之間跳轉(zhuǎn)時(shí)必然會(huì)執(zhí)行的方法

兩個(gè) Activity 之間跳轉(zhuǎn)時(shí)必然會(huì)執(zhí)行的方法

一般情況下比如說(shuō)有兩個(gè) activity , 分別叫 A , B ,當(dāng)在 A 里面激活 B 組件的時(shí)候, A 會(huì)調(diào)用 onPause() 方法,然后 B 調(diào)用 onCreate() , onStart() , onResume() 优妙。

這個(gè)時(shí)候 B 覆蓋了窗體, A 會(huì)調(diào)用 onStop() 方法. 如果 B 是個(gè)透明的,或者 是對(duì)話框的樣式, 就不會(huì)調(diào)用 AonStop() 方法乘综。

3.5 用 Intent 去啟動(dòng)一個(gè)Activity 之外的方法

用 Intent 去啟動(dòng)一個(gè)Activity 之外的方法
  • 使用 adb shell am 命令
  1. am 啟動(dòng)一個(gè) activity
  2. adb shell am start com.example.fuchenxuan/.MainActivity
  3. am 發(fā)送一個(gè)廣播,使用 action
  4. adb shell am broadcast -a magcomm.action.TOUCH_LETTER

3.6 scheme 跳轉(zhuǎn)協(xié)議

scheme跳轉(zhuǎn)協(xié)議

3.6.1 定義

定義
  • 服務(wù)器可以定制化跳轉(zhuǎn) app 頁(yè)面

  • app 可以通過(guò) Scheme 跳轉(zhuǎn)到另一個(gè) app 頁(yè)面

  • 可以通過(guò) h5 頁(yè)面跳轉(zhuǎn) app 原生頁(yè)面

3.6.2 協(xié)議格式:

協(xié)議格式
協(xié)議格式
  • qh 代表 Scheme 協(xié)議名稱

  • test 代表 Scheme 作用的地址域

  • 8080 代表改路徑的端口號(hào)

  • /goods 代表的是指定頁(yè)面(路徑)

  • goodsIdname 代表傳遞的兩個(gè)參數(shù)

3.6.3 Scheme使用

  • 定義一個(gè) Scheme
image
  • 獲取 Scheme 跳轉(zhuǎn)的參數(shù)
image
  • 調(diào)用方式
  1. 原生調(diào)用
image
  1. html調(diào)用
image
  1. 判斷某個(gè)Scheme是否有效
image


四邪意、 Context


4.1 Context , Activity , Appliction 的區(qū)別

Context, Activity, Appliction 的區(qū)別
  • 相同:ActivityApplication 都是 Context 的子類九妈。
  • Context 從字面上理解就是上下文的意思, 在實(shí)際應(yīng)用中它也確實(shí)是起到了管理 上下文環(huán)境中各個(gè)參數(shù)和變量的總用, 方便我們可以簡(jiǎn)單的訪問(wèn)到各種資源。
  • 不同:維護(hù)的生命周期不同雾鬼。Context 維護(hù)的是當(dāng)前的 Activity 的生命周期, Application 維護(hù)的是整個(gè)項(xiàng)目的生命周期萌朱。
  • 使用 context 的時(shí)候, 小心內(nèi)存泄露, 防止內(nèi)存泄露

4.2 Context 是什么

Context 是什么
  • 它描述的是一個(gè)應(yīng)用程序環(huán)境的信息,即上下文。

  • 該類是一個(gè)抽象( abstract class )類, Android 提供了該抽象類的具體實(shí) 現(xiàn)類( ContextIml )策菜。

  • 通過(guò)它我們可以獲取應(yīng)用程序的資源和類, 也包括一些應(yīng)用級(jí)別操作, 例如:啟動(dòng)一個(gè) Activity ,發(fā)送廣播,接受 Intent ,信息,等晶疼。

4.2.1 附加一張 Context 繼承關(guān)系圖

[圖片上傳失敗...(image-de33df-1572405738902)]

4.3 獲取當(dāng)前屏幕 Activity 的對(duì)象

獲取當(dāng)前屏幕Activity的對(duì)象

4.4 Activity 的管理機(jī)制

Activity的管理機(jī)制
  1. 什么是 ActivityRecord
  2. 什么是 TaskRecord
  3. 什么是 ActivityManagerService

4.5 什么是 Activity

什么是 Activity
  • 四大組件之一翠霍,通常一個(gè)用戶交互界面對(duì)應(yīng)一個(gè) activity
  • activityContext 的子類蠢莺,同時(shí)實(shí)現(xiàn)了 window.callbackkeyevent.callback 寒匙,可以處理與窗體用戶交互的事件。
  • 開(kāi)發(fā)中常用的有 FragmentActivity 躏将、ListActivity 蒋情、TabActivityAndroid 4.0Fragment 取代)

五、 進(jìn)程


5.1 Android 進(jìn)程優(yōu)先級(jí)

  • 前臺(tái) / 可見(jiàn) / 服務(wù) / 后臺(tái) / 空
前臺(tái) / 可見(jiàn) / 服務(wù) / 后臺(tái) / 空

5.1.1 前臺(tái)進(jìn)程:Foreground process

前臺(tái)進(jìn)程:Foreground process
  • 用戶正在交互的 ActivityonResume()
  • 當(dāng)某個(gè) Service 綁定正在交互的 Activity
  • 被主動(dòng)調(diào)用為前臺(tái) ServicestartForeground()
  • 組件正在執(zhí)行生命周期的回調(diào)( onCreate() 耸携、onStart() 棵癣、onDestory()
  • BroadcastReceiver 正在執(zhí)行 onReceive()

5.1.2 可見(jiàn)進(jìn)程:Visible process

可見(jiàn)進(jìn)程:Visible process
  • 我們的 Activity 處在 onPause()(沒(méi)有進(jìn)入 onStop()
  • 綁定到前臺(tái) ActivityService

5.1.3 服務(wù)進(jìn)程:Service process

服務(wù)進(jìn)程
  • 簡(jiǎn)單的 startService() 啟動(dòng)。

5.1.4 后臺(tái)進(jìn)程:Background process

后臺(tái)進(jìn)程:Background process
  • 對(duì)用戶沒(méi)有直接影響的進(jìn)程 --- Activity 處于 onStop() 的時(shí)候夺衍。
  • android:process=":xxx"

5.1.5 空進(jìn)程:Empty process

空進(jìn)程:Empty process
  • 不含有任何的活動(dòng)的組件狈谊。( Android 設(shè)計(jì)的,處于緩存的目的沟沙,為了第二次啟動(dòng)更快河劝,采取的一個(gè)權(quán)衡)

5.2 可見(jiàn)進(jìn)程

可見(jiàn)進(jìn)程

可見(jiàn)進(jìn)程指部分程序界面能夠被用戶看見(jiàn),卻不在前臺(tái)與用戶交互的進(jìn)程矛紫。例如赎瞎,我們?cè)谝粋€(gè)界面上彈出一個(gè)對(duì)話框(該對(duì)話框是一個(gè)新的 Activity ),那么在對(duì)話框后面的原界面是可見(jiàn)的颊咬,但是并沒(méi)有與用戶進(jìn)行交互务甥,那么原界面就是可見(jiàn)進(jìn)程牡辽。

  • 一個(gè)進(jìn)程滿足下面任何一個(gè)條件都被認(rèn)為是可視的:
  1. 寄宿著一個(gè)不是前臺(tái)的活動(dòng),但是它對(duì)用戶仍可見(jiàn)(它的 onPause() 方法已經(jīng)被調(diào)用)敞临。舉例來(lái)說(shuō)态辛,這可能發(fā)生在,如果一個(gè)前臺(tái)活動(dòng)在一個(gè)對(duì)話框(其他進(jìn)程的)運(yùn)行之后仍然是可視的挺尿,比如輸入法的彈出時(shí)奏黑。
  2. 寄宿著一個(gè)服務(wù),該服務(wù)綁定到一個(gè)可視的活動(dòng)编矾。
  • 一個(gè)可視進(jìn)程被認(rèn)為是及其重要的且不會(huì)被殺死熟史,除非為了保持前臺(tái)進(jìn)程運(yùn)行。

5.3 服務(wù)進(jìn)程

服務(wù)進(jìn)程
  • 服務(wù)進(jìn)程是通過(guò) startService() 方法啟動(dòng)的進(jìn)程窄俏,但不屬于前臺(tái)進(jìn)程和可見(jiàn)進(jìn)程蹂匹。例如,在后臺(tái)播放音樂(lè)或者在后臺(tái)下載就是服務(wù)進(jìn)程裆操。

  • 系統(tǒng)保持它們運(yùn)行怒详,除非沒(méi)有足夠內(nèi)存來(lái)保證所有的前臺(tái)進(jìn)程和可視進(jìn)程炉媒。

5.4 后臺(tái)進(jìn)程

后臺(tái)進(jìn)程
  • 后臺(tái)進(jìn)程是一個(gè)保持著一個(gè)當(dāng)前對(duì)用戶不可視的活動(dòng)(已經(jīng)調(diào)用 Activity 對(duì)象的 onStop() 方法)(如果還有除了 UI 線程外其他線程在運(yùn)行話踪区,不受影響)。

例如我正在使用 qq 和別人聊天吊骤,這個(gè)時(shí)候 qq 是前臺(tái)進(jìn)程缎岗,但是當(dāng)我點(diǎn)擊 Home 鍵讓 qq 界面消失的時(shí)候,這個(gè)時(shí)候它就轉(zhuǎn)換成了后臺(tái)進(jìn)程白粉。

  • 這些進(jìn)程沒(méi)有直接影響用戶體驗(yàn)传泊,并且可以在任何時(shí)候被殺以收回內(nèi)存用于一個(gè)前臺(tái)、可視鸭巴、服務(wù)進(jìn)程眷细。
  • 一般地有很多后臺(tái)進(jìn)程運(yùn)行著,因此它們保持在一個(gè) LRUleast recently used 鹃祖,即最近最少使用溪椎,如果您學(xué)過(guò)操作系統(tǒng)的話會(huì)覺(jué)得它很熟悉,跟內(nèi)存的頁(yè)面置換算法 LRU 一樣)列表以確保最近使用最多的活動(dòng)的進(jìn)程最后被殺恬口。

5.5 空進(jìn)程

空進(jìn)程
  • 空進(jìn)程是一個(gè)沒(méi)有保持活躍的應(yīng)用程序組件的進(jìn)程校读,不包含任何活躍組件。

  • 保持這個(gè)進(jìn)程可用的唯一原因是作為一個(gè) cache 以提高下次啟動(dòng)組件的速度祖能。系統(tǒng)進(jìn)程殺死這些進(jìn)程歉秫,以在進(jìn)程 cache 和潛在的內(nèi)核 cache 之間平衡整個(gè)系統(tǒng)資源。

  • android 進(jìn)程的回收順序從先到后分別是:空進(jìn)程养铸,后臺(tái)進(jìn)程雁芙,服務(wù)進(jìn)程轧膘,可見(jiàn)進(jìn)程,前臺(tái)進(jìn)程却特。

5.6 什么是 ANR扶供,如何避免

什么是 ANR,如何避免

5.6.1 什么是ANR

什么是ANR
  • ANR 裂明,全稱為 Application Not Responding 椿浓。
  • Android 中,如果你的應(yīng)用程序有一段時(shí)間沒(méi)有響應(yīng)闽晦,系統(tǒng)會(huì)向用戶顯示一個(gè)對(duì)話框扳碍,這個(gè)對(duì)話框稱作應(yīng)用程序無(wú)響應(yīng)對(duì)話框。

5.6.2 用戶行為

用戶行為
  • 用戶可以選擇讓程序繼續(xù)運(yùn)行仙蛉,也可以讓程序停止運(yùn)行笋敞。
  • 他們?cè)谑褂媚愕膽?yīng)用程序時(shí),并不希望每次都要處理這個(gè)對(duì)話框荠瘪。
  • 因此夯巷,在程序里對(duì)響應(yīng)性能的設(shè)計(jì)很重要,這樣哀墓,系統(tǒng)不會(huì)顯示 ANR 給用戶趁餐。

5.6.3 Android不同組件ANR超時(shí)時(shí)間不同

Android不同組件ANR超時(shí)時(shí)間不同
  • 不同的組件發(fā)生 ANR 的時(shí)間不一樣,主線程( Activity 篮绰、Service )是 5 秒后雷,BroadCastReceiver10 秒。

5.6.4 解決方案

解決方案
  1. 將所有耗時(shí)操作吠各,比如訪問(wèn)網(wǎng)絡(luò)臀突,Socket 通信,查詢大量 SQL 語(yǔ)句贾漏,復(fù)雜邏輯計(jì)算等都放在子線程中去候学,然后通過(guò) handler.sendMessagerunonUITread 纵散、AsyncTask 等方式更新 UI 梳码,以確保用戶界面操作的流暢度。
  2. 如果耗時(shí)操作需要讓用戶等待困食,那么可以在界面上顯示進(jìn)度條边翁。

5.7 android的任務(wù)棧 Task

android的任務(wù)棧 Task
  • 一個(gè) Task 包含的就是 activity 集合,android 系統(tǒng)可以通過(guò)任務(wù)棧有序的管理 activity
  • 一個(gè)app當(dāng)中可能不止一個(gè)任務(wù)棧硕盹,在某些情況下符匾,一個(gè) activity 也可以獨(dú)享一個(gè)任務(wù)棧( singleInstance 模式啟動(dòng)的 activity

總結(jié)


  1. 本文基本涵蓋了 Android Activity 的所有知識(shí)點(diǎn)。對(duì)于 App 啟動(dòng)瘩例、AMS 希望大家能根據(jù)文中鏈接或者 Google 搜索的形式繼續(xù)展開(kāi)學(xué)習(xí)啊胶。
  2. 重點(diǎn):關(guān)于 Android 的四大組件甸各,到現(xiàn)在為止我才總結(jié)完 Activity ,馬上我將繼續(xù)針對(duì)焰坪,Service 趣倾,BroadcastRecevier 等,以及事件分發(fā)某饰、滑動(dòng)沖突儒恋、新能優(yōu)化等重要模塊,進(jìn)行全面總結(jié)黔漂,歡迎大家關(guān)注 _yuanhao 的 簡(jiǎn)書(shū) 诫尽,方便及時(shí)接收更新

碼字不易,你的點(diǎn)贊是我總結(jié)的最大動(dòng)力炬守!


Android
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末御毅,一起剝皮案震驚了整個(gè)濱河市智听,隨后出現(xiàn)的幾起案子羽杰,更是在濱河造成了極大的恐慌,老刑警劉巖到推,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件考赛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡莉测,警方通過(guò)查閱死者的電腦和手機(jī)颜骤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捣卤,“玉大人忍抽,你說(shuō)我怎么就攤上這事八孝。” “怎么了鸠项?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵干跛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我祟绊,道長(zhǎng)楼入,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任牧抽,我火速辦了婚禮浅辙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘阎姥。我一直安慰自己记舆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布呼巴。 她就那樣靜靜地躺著泽腮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衣赶。 梳的紋絲不亂的頭發(fā)上诊赊,一...
    開(kāi)封第一講書(shū)人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音府瞄,去河邊找鬼碧磅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛遵馆,可吹牛的內(nèi)容都是我干的鲸郊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼货邓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼秆撮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起换况,我...
    開(kāi)封第一講書(shū)人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤职辨,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后戈二,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體舒裤,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年觉吭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腾供。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖台腥,靈堂內(nèi)的尸體忽然破棺而出宏赘,到底是詐尸還是另有隱情,我是刑警寧澤黎侈,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布察署,位于F島的核電站,受9級(jí)特大地震影響峻汉,放射性物質(zhì)發(fā)生泄漏贴汪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一扳埂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瘤礁,春花似錦阳懂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至赡盘,卻和暖如春号枕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陨享。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工葱淳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抛姑。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓赞厕,卻偏偏與公主長(zhǎng)得像途戒,于是被迫代替她去往敵國(guó)和親喷斋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子星爪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353