
前言
- 學(xué)
Android有一段時(shí)間了,一直都只顧著學(xué)新的東西,最近發(fā)現(xiàn)很多平常用的少的東西竟讓都忘了,趁著這兩天,打算把有關(guān)Activity的內(nèi)容以問(wèn)題的形式梳理出來(lái),也供大家查缺補(bǔ)漏。
本文中,我將一改往日寫(xiě)博客的習(xí)慣,全文用 XMind 將所有知識(shí)點(diǎn)以思維導(dǎo)圖的形式呈現(xiàn),歡迎大家食用~~
文章目錄

方便大家學(xué)習(xí),我在 GitHub 上建立個(gè) 倉(cāng)庫(kù)
倉(cāng)庫(kù)內(nèi)容與博客同步更新。由于我在
稀土掘金簡(jiǎn)書(shū)CSDN博客園等站點(diǎn),都有新內(nèi)容發(fā)布。所以大家可以直接關(guān)注該倉(cāng)庫(kù),以免錯(cuò)過(guò)精彩內(nèi)容!倉(cāng)庫(kù)地址:
超級(jí)干貨!精心歸納Android、JVM、算法等,各位帥氣的老鐵支持一下!給個(gè) Star !
神圖
- 在開(kāi)始之前,先讓我們看看
Android的activity到底都有哪些東西? - 借一張網(wǎng)上很火的圖帶你了解
Activity

一、 生命周期
- 先貼一張聞名遐邇的圖
- 我們生命周期先看看具體有哪些方法回調(diào),在逐一攻破:
[圖片上傳失敗...(image-76615c-1572405738902)]
1.1 Dialog 彈出時(shí)

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

不設(shè)置
Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次,切豎屏?xí)r會(huì)執(zhí)行兩次設(shè)置
Activity的android:configChanges="orientation"時(shí),切屏還是會(huì)重新調(diào)用各個(gè)生命周期,切橫、豎屏?xí)r只會(huì)執(zhí)行一次設(shè)置
Activity的android: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!
1.3 不同場(chǎng)景下 Activity 生命周期的變化過(guò)程

- 啟動(dòng)
Activity:onCreate()--->onStart()--->onResume(),Activity進(jìn)入運(yùn)行狀態(tài)。 - 鎖屏?xí)r會(huì)執(zhí)行
onPause()和onStop(), 而開(kāi)屏?xí)r則應(yīng)該執(zhí)行onStart()onResume()

-
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è)置成窗口的樣式

只需要給我們的 Activity 配置如下屬性即可。
android:theme="@android:style/Theme.Dialog"
1.5 退出已調(diào)用多個(gè) Activity 的 Application
- 通常情況用戶退出一個(gè)
Activity只需按返回鍵,我們寫(xiě)代碼想退出activity直接調(diào)用finish()方法就行。

- 發(fā)送特定廣播:
- 在需要結(jié)束應(yīng)用時(shí), 發(fā)送一個(gè)特定的廣播,每個(gè)
Activity收到廣播后,關(guān)閉 即可。 - 給某個(gè)
activity注冊(cè)接受接受廣播的意圖registerReceiver(receiver, filter) - 如果過(guò)接受到的是 關(guān)閉
activity的廣播activity finish()掉
- 遞歸退出
- 就調(diào)用
finish()方法 把當(dāng)前的Activity退出 - 在打開(kāi)新的
Activity時(shí)使用startActivityForResult, 然后自己加標(biāo)志, 在onActivityResult中處理, 遞歸關(guān)閉。
- 其實(shí)
- 也可以通過(guò)
intent的flag來(lái)實(shí)現(xiàn)intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)激活一個(gè)新的activity。 - 此時(shí)如果該任務(wù)棧中已經(jīng)有該
Activity, 那么系統(tǒng)會(huì)把這個(gè)Activity上面的所有Activity干掉。 - 其實(shí)相當(dāng)于給
Activity配置的啟動(dòng)模式為singleTask。
- 記錄打開(kāi)的
Activity
- 每打開(kāi)一個(gè)
Activity, 就記錄下來(lái)。 - 在需要退出時(shí) , 關(guān)閉每一個(gè)
Activity
1.6 鎖定屏與解鎖屏幕,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à)

- 可以通過(guò)兩種方式 , 一是通過(guò)定義
Activity的主題 ,二是通過(guò)覆寫(xiě)Activity的overridePendingTransition方法。 - 通過(guò)設(shè)置主題樣式在
styles.xml中編輯代碼 , 添加themes.xml文件:在AndroidManifest.xml中給指定的Activity指定theme。 - 覆寫(xiě)
overridePendingTransition方法:overridePendingTransition(R.anim.fade, R.anim.hold);
1.8 Activity 的四種狀態(tài)

-
runnig:用戶可以點(diǎn)擊,activity處于棧頂狀態(tài)。 -
paused:activity失去焦點(diǎn)的時(shí)候,被一個(gè)非全屏的activity占據(jù)或者被一個(gè)透明的activity覆蓋,這個(gè)狀態(tài)的activity并沒(méi)有銷(xiāo)毀,它所有的狀態(tài)信息和成員變量仍然存在,只是不能夠被點(diǎn)擊。(內(nèi)存緊張的情況,這個(gè)activity有可能被回收)

-
stopped:這個(gè)activity被另外一個(gè)activity完全覆蓋,但是這個(gè)activity的所有狀態(tài)信息和成員變量仍然存在(除了內(nèi)存緊張) -
killed:這個(gè)activity已經(jīng)被銷(xiāo)毀,其所有的狀態(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()
- 搞懂這個(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

如果
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)模式

-
Activity一共有四種launchMode:standard、singleTop、singleTask、singleInstance。

-
Standard模式(默認(rèn)模式)
說(shuō)明: 每次啟動(dòng)一個(gè)
Activity都會(huì)又一次創(chuàng)建一個(gè)新的實(shí)例入棧,無(wú)論這個(gè)實(shí)例是否存在。生命周期:每次被創(chuàng)建的實(shí)例
Activity的生命周期符合典型情況,它的onCreate、onStart、onResume都會(huì)被調(diào)用。舉例:此時(shí)
Activity棧中以此有A、B、C三個(gè)Activity,此時(shí)C處于棧頂,啟動(dòng)模式為Standard模式。若在C Activity中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)同類(lèi)型的C Activity。結(jié)果是還有一個(gè)C Activity進(jìn)入棧中,成為棧頂。

-
SingleTop模式(棧頂復(fù)用模式)
說(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模式一樣。生命周期:若情況一中棧頂?shù)?
Activity被直接復(fù)用時(shí),它的onCreate、onStart不會(huì)被系統(tǒng)調(diào)用,由于它并沒(méi)有發(fā)生改變??墒且粋€(gè)新的方法onNewIntent會(huì)被回調(diào)(Activity被正常創(chuàng)建時(shí)不會(huì)回調(diào)此方法)。舉例:此時(shí)
Activity棧中以此有A、B、C三個(gè)Activity,此時(shí)C處于棧頂,啟動(dòng)模式為SingleTop模式。情況一:在C Activity中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)同類(lèi)型的C Activity。結(jié)果是直接復(fù)用棧頂?shù)?C Activity。情況二:在C Activity中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)A Activity。結(jié)果是創(chuàng)建一個(gè)新的Activity入棧。成為棧頂。

-
SingleTask模式(棧內(nèi)復(fù)用模式)
說(shuō)明:若須要?jiǎng)?chuàng)建的
Activity已經(jīng)處于棧中時(shí),此時(shí)不會(huì)創(chuàng)建新的Activity,而是將存在棧中的Activity上面的其他Activity所有銷(xiāo)毀,使它成為棧頂。如果是在別的應(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中。生命周期:同
SingleTop模式中的情況一同樣。僅僅會(huì)又一次回調(diào)Activity中的onNewIntent方法舉例:此時(shí)
Activity棧中以此有A、B、C三個(gè)Activity。此時(shí)C處于棧頂,啟動(dòng)模式為SingleTask模式。情況一:在C Activity中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)同類(lèi)型的C Activity。結(jié)果是直接用棧頂?shù)?C Activity。情況二:在C Activity中加入點(diǎn)擊事件,須要跳轉(zhuǎn)到還有一個(gè)A Activity。結(jié)果是將A Activity上面的B、C所有銷(xiāo)毀,使A Activity成為棧頂。

-
SingleInstance模式(單實(shí)例模式)
說(shuō)明:
SingleInstance比較特殊,是全局單例模式,是一種加強(qiáng)的SingleTask模式。它除了具有它所有特性外,還加強(qiáng)了一點(diǎn):只有一個(gè)實(shí)例,并且這個(gè)實(shí)例獨(dú)立運(yùn)行在一個(gè)task中,這個(gè)task只有這個(gè)實(shí)例,不允許有別的Activity存在。這個(gè)經(jīng)常使用于系統(tǒng)中的應(yīng)用,比如
Launch、鎖屏鍵的應(yīng)用等等,整個(gè)系統(tǒng)中僅僅有一個(gè)!所以在我們的應(yīng)用中一般不會(huì)用到。了解就可以。舉例:比方
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)銷(xiāo)毀。
2.2 啟動(dòng)模式的使用方式

- 在
Manifest.xml中指定Activity啟動(dòng)模式
- 一種靜態(tài)的指定方法
- 在
Manifest.xml文件里聲明Activity的同一時(shí)候指定它的啟動(dòng)模式 - 這樣在代碼中跳轉(zhuǎn)時(shí)會(huì)依照指定的模式來(lái)創(chuàng)建
Activity。
- 啟動(dòng)
Activity時(shí)。在Intent中指定啟動(dòng)模式去創(chuàng)建Activity
- 一種動(dòng)態(tài)的啟動(dòng)模式
- 在
new一個(gè)Intent后 - 通過(guò)
Intent的addFlags方法去動(dòng)態(tài)指定一個(gè)啟動(dòng)模式。
- 注意:以上兩種方式都能夠?yàn)?
Activity指定啟動(dòng)模式,可是二者還是有差別的。
優(yōu)先級(jí):動(dòng)態(tài)指定方式即另外一種比第一種優(yōu)先級(jí)要高,若兩者同一時(shí)候存在,以另外一種方式為準(zhǔn)。
限定范圍:第一種方式無(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ō)SingleTop和SingleTask模式的運(yùn)用場(chǎng)景:

-
SingleTask模式的運(yùn)用場(chǎng)景
- 最常見(jiàn)的應(yīng)用場(chǎng)景就是保持我們應(yīng)用開(kāi)啟后僅僅有一個(gè)
Activity的實(shí)例。 - 最典型的樣例就是應(yīng)用中展示的主頁(yè)(
Home頁(yè))。 - 假設(shè)用戶在主頁(yè)跳轉(zhuǎn)到其他頁(yè)面,運(yùn)行多次操作后想返回到主頁(yè),假設(shè)不使用
SingleTask模式,在點(diǎn)擊返回的過(guò)程中會(huì)多次看到主頁(yè),這明顯就是設(shè)計(jì)不合理了。
-
SingleTop模式的運(yùn)用場(chǎng)景
- 假設(shè)你在當(dāng)前的
Activity中又要啟動(dòng)同類(lèi)型的Activity - 此時(shí)建議將此類(lèi)型
Activity的啟動(dòng)模式指定為SingleTop,能夠降低Activity的創(chuàng)建,節(jié)省內(nèi)存!
- 注意:復(fù)用
Activity時(shí)的生命周期回調(diào)
- 這里還須要考慮一個(gè)
Activity跳轉(zhuǎn)時(shí)攜帶頁(yè)面參數(shù)的問(wèn)題。 - 由于當(dāng)一個(gè)
Activity設(shè)置了SingleTop或者SingleTask模式后,跳轉(zhuǎn)此Activity出現(xiàn)復(fù)用原有Activity的情況時(shí),此Activity的onCreate方法將不會(huì)再次運(yùn)行。onCreate方法僅僅會(huì)在第一次創(chuàng)建Activity時(shí)被運(yùn)行。 - 而一般
onCreate方法中會(huì)進(jìn)行該頁(yè)面的數(shù)據(jù)初始化、UI初始化,假設(shè)頁(yè)面的展示數(shù)據(jù)無(wú)關(guān)頁(yè)面跳轉(zhuǎn)傳遞的參數(shù),則不必操心此問(wèn)題 - 若頁(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)具體解釋?zhuān)?/li>
以上代碼中的
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

- 這個(gè)問(wèn)題其實(shí)也是比較簡(jiǎn)單的,就是不要在
Activity的onCreate方法中執(zhí)行過(guò)多繁重的操作,并且在onPasue方法中同樣不能做過(guò)多的耗時(shí)操作。
2.5 啟動(dòng)流程
注意!這里并不是要回答
Activity的生命周期!
2.6 Activity 的 Flags

標(biāo)記位既能夠設(shè)定Activity的啟動(dòng)模式,如同上面介紹的,在動(dòng)態(tài)指定啟動(dòng)模式,比方
FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_SINGLE_TOP等。它還能夠影響Activity的運(yùn)行狀態(tài) ,比方FLAG_ACTIVITY_CLEAN_TOP和FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS等。以下介紹幾個(gè)基本的標(biāo)記位,切勿死記,理解幾個(gè)就可以,須要時(shí)再查官方文檔。

FLAG_ACTIVITY_NEW_TASK
- 作用是為
Activity指定“SingleTask”啟動(dòng)模式。跟在AndroidMainfest.xml指定效果同樣
FLAG_ACTIVITY_SINGLE_TOP
- 作用是為
Activity指定“SingleTop”啟動(dòng)模式,跟在AndroidMainfest.xml指定效果同樣。
FLAG_ACTIVITY_CLEAN_TOP
- 具有此標(biāo)記位的
Activity,啟動(dòng)時(shí)會(huì)將與該Activity在同一任務(wù)棧的其他Activity出棧。 - 一般與
SingleTask啟動(dòng)模式一起出現(xiàn)。 - 它會(huì)完畢
SingleTask的作用。 - 但事實(shí)上
SingleTask啟動(dòng)模式默認(rèn)具有此標(biāo)記位的作用
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- 具有此標(biāo)記位的
Activity不會(huì)出如今歷史Activity的列表中 - 使用場(chǎng)景:當(dāng)某些情況下我們不希望用戶通過(guò)歷史列表回到
Activity時(shí),此標(biāo)記位便體現(xiàn)了它的效果。 - 它等同于在
xml中指定Activity的屬性.
2.7 onNewInstent()方法什么時(shí)候執(zhí)行

這個(gè)是啟動(dòng)模式中的了,當(dāng)此 Activity 的實(shí)例已經(jīng)存在,并且此時(shí)的啟動(dòng)模式為 SingleTask 和 SingleInstance ,另外當(dāng)這個(gè)實(shí)例位于棧頂且啟動(dòng)模式為 SingleTop 時(shí)也會(huì)觸發(fā) onNewInstent() 。
三、 數(shù)據(jù)
3.1 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)行

Activity的onSaveInstanceState()和onRestoreInstanceState()并不是生命周期方法,它們不同于onCreate()、onPause()等生命周期方法,它們并不一定會(huì)被觸發(fā)。onSaveInstanceState()方法,當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足、用戶直接按Home鍵)由系統(tǒng)銷(xiāo)毀一個(gè)Activity,onSaveInstanceState()會(huì)被調(diào)用。但是當(dāng)用戶主動(dòng)去銷(xiāo)毀一個(gè)
Activity時(shí),例如在應(yīng)用中按返回鍵,onSaveInstanceState()就不會(huì)被調(diào)用。除非該
activity不是被用戶主動(dòng)銷(xiāo)毀的,通常onSaveInstanceState()只適合用于保存一些臨時(shí)性的狀態(tài),而onPause()適合用于數(shù)據(jù)的持久化保存。
3.3 onSaveInstanceState() 被執(zhí)行的場(chǎng)景

- 系統(tǒng)不知道你按下
HOME后要運(yùn)行多少其他的程序,自然也不知道activity A是否會(huì)被銷(xiāo)毀 - 因此系統(tǒng)都會(huì)調(diào)用
onSaveInstanceState(),讓用戶有機(jī)會(huì)保存某些非永久性的數(shù)據(jù)。以下幾種情況的分析都遵循該原則:
- 當(dāng)用戶按下
HOME鍵時(shí) - 長(zhǎng)按
HOME鍵,選擇運(yùn)行其他的程序時(shí) - 鎖屏?xí)r
- 從
activity A中啟動(dòng)一個(gè)新的activity時(shí) - 屏幕方向切換時(shí)
3.4 兩個(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)用 A 的 onStop() 方法。
3.5 用 Intent 去啟動(dòng)一個(gè)Activity 之外的方法

- 使用
adb shell am命令
-
am啟動(dòng)一個(gè)activity adb shell am start com.example.fuchenxuan/.MainActivity-
am發(fā)送一個(gè)廣播,使用action adb shell am broadcast -a magcomm.action.TOUCH_LETTER
3.6 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é)議格式:

qh代表Scheme協(xié)議名稱(chēng)test代表Scheme作用的地址域8080代表改路徑的端口號(hào)/goods代表的是指定頁(yè)面(路徑)goodsId和name代表傳遞的兩個(gè)參數(shù)
3.6.3 Scheme使用
- 定義一個(gè)
Scheme
- 獲取
Scheme跳轉(zhuǎn)的參數(shù)
- 調(diào)用方式
- 原生調(diào)用
- html調(diào)用
- 判斷某個(gè)Scheme是否有效
- 關(guān)于scheme跳轉(zhuǎn)協(xié)議,可以查看下面的博客,站在巨人的肩膀上,才能看得更遠(yuǎn)
Android產(chǎn)品研發(fā)(十一)-->應(yīng)用內(nèi)跳轉(zhuǎn)Scheme協(xié)議
四、 Context
4.1 Context , Activity , Appliction 的區(qū)別

- 相同:
Activity和Application都是Context的子類(lèi)。 -
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 是什么

它描述的是一個(gè)應(yīng)用程序環(huán)境的信息,即上下文。
該類(lèi)是一個(gè)抽象(
abstract class)類(lèi),Android提供了該抽象類(lèi)的具體實(shí) 現(xiàn)類(lèi)(ContextIml)。通過(guò)它我們可以獲取應(yīng)用程序的資源和類(lèi), 也包括一些應(yīng)用級(jí)別操作, 例如:啟動(dòng)一個(gè)
Activity,發(fā)送廣播,接受Intent,信息,等。
4.2.1 附加一張 Context 繼承關(guān)系圖
[圖片上傳失敗...(image-de33df-1572405738902)]
4.3 獲取當(dāng)前屏幕 Activity 的對(duì)象

- 使用 ActivityLifecycleCallbacks
Android 如何獲取當(dāng)前Activity實(shí)例對(duì)象?
4.4 Activity 的管理機(jī)制

面試官問(wèn)這個(gè)問(wèn)題,想看看大家對(duì)Activity了解是否深入:
- 什么是 ActivityRecord
- 什么是 TaskRecord
- 什么是 ActivityManagerService
4.5 什么是 Activity

- 四大組件之一,通常一個(gè)用戶交互界面對(duì)應(yīng)一個(gè)
activity。 -
activity是Context的子類(lèi),同時(shí)實(shí)現(xiàn)了window.callback和keyevent.callback,可以處理與窗體用戶交互的事件。 - 開(kāi)發(fā)中常用的有
FragmentActivity、ListActivity、TabActivity(Android 4.0被Fragment取代)
五、 進(jìn)程
5.1 Android 進(jìn)程優(yōu)先級(jí)
- 前臺(tái) / 可見(jiàn) / 服務(wù) / 后臺(tái) / 空

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

- 用戶正在交互的
Activity(onResume()) - 當(dāng)某個(gè)
Service綁定正在交互的Activity - 被主動(dòng)調(diào)用為前臺(tái)
Service(startForeground()) - 組件正在執(zhí)行生命周期的回調(diào)(
onCreate()、onStart()、onDestory()) -
BroadcastReceiver正在執(zhí)行onReceive()
5.1.2 可見(jiàn)進(jìn)程:Visible process

- 我們的
Activity處在onPause()(沒(méi)有進(jìn)入onStop()) - 綁定到前臺(tái)
Activity的Service
5.1.3 服務(wù)進(jìn)程:Service process

- 簡(jiǎn)單的
startService()啟動(dòng)。
5.1.4 后臺(tái)進(jìn)程:Background process

- 對(duì)用戶沒(méi)有直接影響的進(jìn)程 ---
Activity處于onStop()的時(shí)候。 android:process=":xxx"
5.1.5 空進(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),卻不在前臺(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)為是可視的:
- 寄宿著一個(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í)。 - 寄宿著一個(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)程是通過(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)程是一個(gè)保持著一個(gè)當(dāng)前對(duì)用戶不可視的活動(dòng)(已經(jīng)調(diào)用
Activity對(duì)象的onStop()方法)(如果還有除了UI線程外其他線程在運(yùn)行話,不受影響)。
例如我正在使用
Home鍵讓
- 這些進(jìn)程沒(méi)有直接影響用戶體驗(yàn),并且可以在任何時(shí)候被殺以收回內(nèi)存用于一個(gè)前臺(tái)、可視、服務(wù)進(jìn)程。
- 一般地有很多后臺(tái)進(jìn)程運(yùn)行著,因此它們保持在一個(gè)
LRU(least recently used,即最近最少使用,如果您學(xué)過(guò)操作系統(tǒng)的話會(huì)覺(jué)得它很熟悉,跟內(nèi)存的頁(yè)面置換算法LRU一樣)列表以確保最近使用最多的活動(dòng)的進(jìn)程最后被殺。
5.5 空進(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,如何避免

5.6.1 什么是ANR

-
ANR,全稱(chēng)為Application Not Responding。 - 在
Android中,如果你的應(yīng)用程序有一段時(shí)間沒(méi)有響應(yīng),系統(tǒng)會(huì)向用戶顯示一個(gè)對(duì)話框,這個(gè)對(duì)話框稱(chēng)作應(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í)間不同

- 不同的組件發(fā)生
ANR的時(shí)間不一樣,主線程(Activity、Service)是5秒,BroadCastReceiver是10秒。
5.6.4 解決方案

- 將所有耗時(shí)操作,比如訪問(wèn)網(wǎng)絡(luò),
Socket通信,查詢(xún)大量SQL語(yǔ)句,復(fù)雜邏輯計(jì)算等都放在子線程中去,然后通過(guò)handler.sendMessage、runonUITread、AsyncTask等方式更新UI,以確保用戶界面操作的流暢度。 - 如果耗時(shí)操作需要讓用戶等待,那么可以在界面上顯示進(jìn)度條。
5.7 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é)
- 本文基本涵蓋了
Android Activity的所有知識(shí)點(diǎn)。對(duì)于App啟動(dòng)、AMS希望大家能根據(jù)文中鏈接或者Google搜索的形式繼續(xù)展開(kāi)學(xué)習(xí)。 -
重點(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)力!
由于我在「稀土掘金」「簡(jiǎn)書(shū)」「
CSDN」「博客園」等站點(diǎn),都有新內(nèi)容發(fā)布。所以大家可以直接關(guān)注我的GitHub倉(cāng)庫(kù),以免錯(cuò)過(guò)精彩內(nèi)容!倉(cāng)庫(kù)地址:
超級(jí)干貨!精心歸納Android、JVM、算法等,各位帥氣的老鐵支持一下!給個(gè) Star !一萬(wàn)多字長(zhǎng)文,加上精美思維導(dǎo)圖,記得點(diǎn)贊哦,歡迎關(guān)注 _yuanhao 的 簡(jiǎn)書(shū) ,我們下篇文章見(jiàn)!
