Android 群英傳筆記
第一章Android體系與系統(tǒng)架構(gòu)
第二章 Android開發(fā)工具及技巧
第三章 Android控件架構(gòu)與事件攔截機(jī)制
第四章 ListView 使用技巧
第五章 Android Scroll 分析
第六章 Android 繪圖機(jī)制與屏幕適配
第七章 Android 動畫機(jī)制與使用技巧
第八章 Activity與Activity調(diào)用棧分析
第九章 Android 系統(tǒng)信息與安全機(jī)制
第十章 Android性能優(yōu)化
本文出自:
http://m.itdecent.cn/u/a1251e598483
這一章的知識相對簡單,但是Activity 是我們開發(fā)中接觸最多的,可能對生命周期,啟動模式,相對的比較了解一點,關(guān)于Activity的啟動,銷毀,任務(wù)棧的使用,我還是簡單的記錄一下吧,權(quán)當(dāng)復(fù)習(xí)了;
Activity是整個應(yīng)用用戶交互的核心組件,了解Activity的工作模式,生命周期和管理方式,是了解Android的基礎(chǔ),本節(jié)主講
- Activity的生命周期與工作模式
- Activity調(diào)用棧管理
Activity
Activity作為四大組建出現(xiàn)平率最高的組件,我們在哪里都能看到他,就讓我們一起先來了解一下他的生命周期
Activity是用戶交互的第一接口,他提供了一個用戶完成指令的窗口,當(dāng)開發(fā)者創(chuàng)建Activity之后,通過調(diào)用setContentView來指定一個窗口界面,并以此為基礎(chǔ),提供給用戶交互的接口,系統(tǒng)采用Activity棧的方式來管理Activity
Activity一個最大的特點就是擁有多種形態(tài),他可以在多種形態(tài)中自由切換,以此來控制自己的生命周期
1.Activity/Running
這個時候,Activity處于Activity棧的最頂層,可見,并與用戶進(jìn)行交互
2.Paused
Activity失去焦點,被一個新的非全屏的Activity或者一個透明的Activity放置在棧頂時,Activity就轉(zhuǎn)換成了qaused形態(tài),他是去了與用戶交互的能力,所有狀態(tài)信息,成員變量都還保留著,只有在系統(tǒng)內(nèi)存極地的情況下,才會被系統(tǒng)回收
3.Stopped
如果一個Activity被另一個Activity完全覆蓋,那么Activity就會進(jìn)入stop形態(tài),此時他不在可見,但依然保留著所有的狀態(tài)和成員變量
4.Killed
當(dāng)Activity被系統(tǒng)回收或者Activity從來沒有創(chuàng)建過,Activity就處于killed狀態(tài),
由此可見,用戶的不同操作,會讓Activity進(jìn)入四種不同的狀態(tài),而開發(fā)者,只能控制其生,卻不能控制其死
生命周期
Google給了我們一張圖來表示Activity的生命周期,他希望Activity能被開發(fā)者所控制,而不是一匹脫韁的野馬

開發(fā)者必然不必實現(xiàn)所有的生命周期方法,但是必須知道每一個生命周期的含義,可以讓我們更好的掌控Activity,讓他能完成你所期望的效果
- Activity啟動和銷毀過程
在系統(tǒng)調(diào)用onCreate方法之后,就會馬上調(diào)用onStart,然后繼續(xù)調(diào)用onResume來進(jìn)圖運行狀態(tài),最后都會停在onResume狀態(tài),完成啟動,系統(tǒng)會調(diào)用onDestroy來結(jié)束一個Activity的生命周期讓他毀掉kill狀態(tài)
以上就是一個Activity的啟動和銷毀的過程
- onCreate中創(chuàng)建基本的UI元素
- onPause和onStop:清除Acvtivity的資源,避免浪費
- onDestroy:因為引用會在Activity銷毀的時候銷毀,而線程不會,所以清除開啟的線程
- Activity的暫停和恢復(fù)過程
當(dāng)棧頂?shù)腁ctivity部分不可見的時候,就會倒置Activity進(jìn)入onPause
- onPause:釋放系統(tǒng)資源,
- onResume:需要重新初始化onPause釋放的資源
- Activity的停止過程
棧頂?shù)腁ctivity部分不可見的時候,實際上后續(xù)會有兩種可能,從部分不可見到可見,也就是恢復(fù)過程,從部分不可見到完全不可見,也就是停止過程,系統(tǒng)在當(dāng)前Activity不可見的時候調(diào)用onPause
- Activity的重新創(chuàng)建過程
最后我們來看看Activity是如何重新創(chuàng)建的,如果你的系統(tǒng)長時間處于stop的狀態(tài),而此時系統(tǒng)需要更多的內(nèi)存或者系統(tǒng)內(nèi)存比較緊張的時候,系統(tǒng)就會回收你的Activity,而系統(tǒng)為了補(bǔ)償你,會將你的Activity狀態(tài)通過onRestoreInstanceState()方法保存到Bundle中去,當(dāng)然你也可以額外增加鍵值對去保存這些狀態(tài),當(dāng)你重新需要創(chuàng)建這個Activity的時候,保存的Bundle對象就會傳遞到Activity的onRestoreInstanceState()方法中去與onCreate方法中去,這也是onCreate的重要參數(shù)——saveInstanceState的來源
不過這里要注意的一點就是savedInstanceState方法并不是每次當(dāng)Activity離開前臺就會調(diào)用,如果用戶使用finish方法結(jié)束,則不會調(diào)用,而且Android系統(tǒng)已經(jīng)默認(rèn)實現(xiàn)了控件的緩存狀態(tài),來減少開發(fā)者需要實現(xiàn)的緩存邏輯
Android任務(wù)棧簡介
一個Android應(yīng)用程序功能通常會被拆分為多個Activity,而各個Activity之間通過Intcnt進(jìn)行連接,而Android系統(tǒng),通過棧結(jié)構(gòu)來保存整個App的Activity,棧底的元素是整個任務(wù)棧的發(fā)起者。一個合理的任務(wù)調(diào)度棧不僅是性能的保證, 更是提供性能的基礎(chǔ)。
當(dāng)一個App啟動時,如果當(dāng)前環(huán)境中不存在該App的任務(wù)棧,那么系統(tǒng)就會創(chuàng)建一個任務(wù)棧,這個app所啟動的Activity都將在這個任務(wù)棧中被管理,這個棧也被稱為Task?,即表示若干個acnVity的集合,他們組合在一起形成一個Task。另外,需要特別注意的是,一個Task中的ActiVity可以來自不同的App,同一個App的Acnvity也可能不在一個Task中。
關(guān)于棧結(jié)構(gòu),相信大家都不會太陌生一一后進(jìn)先出(lastin First out)的線性表。 根據(jù)Activity在當(dāng)前棧結(jié)構(gòu)中的位置,來決定該Acavity的狀態(tài)。先來看看正常情況下的android任務(wù)棧,當(dāng)一個Activity啟動了另一個Activity的時候,新啟動的Acnvity就會置于任務(wù)棧的頂
端, 并處于活動狀態(tài),而啟動它的Activity雖然功成身退,但依然保留在任務(wù)棧中, 處于停止?fàn)顟B(tài),當(dāng)用戶按下返回鍵或者調(diào)用finish()方法時,系統(tǒng)會移除頂部Activity,讓后面的Acnvity恢復(fù)活動狀態(tài)。 當(dāng)然,世界不可能一直這么“和諧”,可以給Activity設(shè)置一些“特權(quán)’,來打
破這種“和諧”的模式。這種特權(quán),就是通過在 AndroidMainifest 文件中的屬性android:1aunchMode來設(shè)置或者是通過intent的flag來設(shè)置的。
AndroidManifest啟動模式
- standard
- singleTop
- singleTask
- singleInstance
1.standard
默認(rèn)的啟動模式,如果不指定Activity的啟動模式,則使用這種模式來啟動Activity,每次點擊standard模式創(chuàng)建Activity之后,都會創(chuàng)建新的MainActivity覆蓋在原有的Activity上,
- singleTop
如果指定Activity的啟動方式為singletop,那么在啟動的時候,系統(tǒng)會判斷當(dāng)前棧頂Activity是不是要啟動的那個,如果是則不創(chuàng)建新的Activity,如果不是則創(chuàng)建新的Activity,這種模式通常適用于接收到消息后顯示的界面,列入QQ接收到消息后彈出Activity,如果一次來10條,總不能彈10次吧,
這種啟動模式雖然不能創(chuàng)建新的實例,但是系統(tǒng)任然會在Activity啟動的時候調(diào)用onNewIntent()方法,舉例子,如果當(dāng)前任務(wù)棧中有ABC三個Activity,而C的啟動模式是singleTop,那么這個時候再啟動C,那么系統(tǒng)就不會去創(chuàng)建C的實例了,而是會調(diào)用C的onNewIntent方法,當(dāng)前任務(wù)棧依然是ABC三個Activity
- singleTask
singleTask模式和singleTop模式有點類似,只不過singleTop是檢測棧頂元素是否需要啟動的Activity,而singleTask是檢測整個Activity棧中是否存在當(dāng)前啟動的Activity,如果存在,就將他置于棧頂,并且將以上的Activity全部銷毀,不過這里也是指在同一個APP中啟動整個singleTask的Activity,如果是其他的程序以singleTask模式來啟動整個Activity,那么他將創(chuàng)建一個新的任務(wù)棧,不過這里有一點需要注意的是,如果啟動的模式為singleTask的Activity已經(jīng)在后臺的一個棧中,那么啟動后,后臺的一個任務(wù)棧將一起被切換到前臺,,借助官網(wǎng)的一張圖我們可能更好的理解

當(dāng)Activity2啟動ActivityY的時候(啟動模式為singleTask),他所在的task被切換到前臺,且按返回鍵返回的時候,也會先返回ActivityY所在Task的Activity
可以發(fā)現(xiàn),使用這個模式創(chuàng)建的Activity不是在新的任務(wù)棧中被打開,就是將已打開的Activity換到前臺, 所以這種啟動模式通??梢杂脕硗顺稣麄€應(yīng)用,將主Activity設(shè)為singlelask模式,然后在要退出的AcnVity中轉(zhuǎn)到主Activity,從而將主Activity之上的Activity全部銷毀,然后重寫主ActlVity的onNewIntent方法 在方法中加上一句finish,將最后一個Activity結(jié)束掉。
- singleInstance
singieInstance這種啟動模式和使用的瀏覽器工作原理類似。在多個程序中訪問瀏覽器時,如果當(dāng)前瀏覽器沒有打開則打開瀏覽器, 否則會在當(dāng)前打開的瀏覽器中訪問. 申明為singleInstance的Activity會出現(xiàn)在一個新的任務(wù)棧中而且該任務(wù)棧中只存在這一個Activity,舉個例子來說,如果應(yīng)用A的任務(wù)棧中創(chuàng)建了MainActivity實例,且啟動模式為singleInstance,如果應(yīng)用B也要激活MainActivity 則不需要創(chuàng)建,兩個應(yīng)用共享該Activity實例,這種啟動模式常用于需要與程序分離的界面: 如在setupWizard中調(diào)用緊急呼叫,就是使用這種啟
動模式
關(guān)于singleTop和singleInstance這兩種啟動模式還有一點需要特殊說明: 如果在一個singleTop或者singleInstance的Activity中通過startActivityForResultO方法來啟動另一個ActivityB, 那么系統(tǒng)將直接返回Activity_RESULT_CANCELED而不會再去等待返回。 這是由于系統(tǒng)在framework層做了對這兩種啟動模式的限制, 因為Android開發(fā)者認(rèn)為,不同的Task中,默認(rèn)是不能傳遞數(shù)據(jù)的。如果一定要傳遞數(shù)據(jù)的話,那么只能通過Intent去綁定數(shù)據(jù)
Intent Flag啟動模式
下面來介紹一些常用的Flag
- Intent.FLAG-ACTIVITY-NEW-TASK
使用一個新的Task來啟動一個Activity,但啟動的每個Activity都在新的Task棧中,該flag通常使用在從Service中啟動的Activity場景,由于Service中并不存在Activity棧,所以用該flag來創(chuàng)建一個新的Activity棧,并創(chuàng)建新的Activity實例
- FLAG-ACTIVITY-SINGLE-TOP
使用singletop模式來啟動一個Activity,與指定android:launchMode=”singleTop”效果相同
- FLAG-ACTIVITY-CLEAR-TOP
使用SingleTask模式來啟動一個Activity,與指定android:launchMode=”singleTask”效果相同
- FLAG-ACTIVITY-NO-HISTORY
使用這種模式啟動Activity,當(dāng)該Activity啟動其他Activity后,該Activity就消失了,不會保留在Activity棧中,例如A-B,B中以這種模式啟動C,C再啟動D,則當(dāng)前Activity棧為ABD
清空任務(wù)棧
系統(tǒng)同樣提供了清空任務(wù)棧的方法來讓我們講一個Task清空,通常情況下,我們可以在Activity的標(biāo)簽上使用以下幾種屬性來清空任務(wù)棧
- clearTaskOnLaunch
clearTaskOnLaunch屬性顧名思義,就是每次返回Activity的時候,都將該Activity上的所有Activity清除,通過這個屬性,可以讓這個task每次初始化的時候,都只有一個Activity
- finishTaskOnLaunch
finishTaskOnLaunch這個屬性和clearTaskOnLaunch有點類似,只不過clearTaskOnLaunch作用在別人身上,而finishTaskOnLaunch作用在自己身上,通過這個屬性,當(dāng)離開這個Activity所處的task,那么用戶再返回的時候,該Activity會被finish掉
- alwaysRetainTaskState
alwaysRetainTaskState屬性給了task一道免死金牌,如果將Activity這個屬性設(shè)置為true,那么該Activity所在的task將不接受任何清除命令,一直保持當(dāng)前task的狀態(tài)
Activity任務(wù)棧使用
我們使用Activity任務(wù)棧的各種啟動模式和清理方法,是為了更好地使用App中actvity,合理地設(shè)置Activity的啟動模式會讓程序運行更有效率,用戶體驗更好。但任務(wù)棧雖好, 卻也不能濫用 如果過度地使用Activity任務(wù)棧,則會導(dǎo)致整個App的棧管理混亂,不利于以后程序的拓展,而且在容易出現(xiàn)由于任務(wù)棧導(dǎo)致的顯示異常,這樣的bug是很難調(diào)的.所以,在App中使用Activity任務(wù)棧一定要根據(jù)實際項目的需要,而不是為了使用任務(wù)棧而使用任務(wù)棧。
好了,這一章的內(nèi)容 相對比較基礎(chǔ),但是這也是做為一個Android 開發(fā) 必須要掌握的基礎(chǔ)知識,基礎(chǔ)的面試還是會考這些內(nèi)容的.