一犹菱,初識(shí)
由于Android系統(tǒng)資源的有限性以及不同場(chǎng)景需求的不同截歉,Android四大組件可以對(duì)應(yīng)不同的使用場(chǎng)景從而提高系統(tǒng)資源的利用率稽鞭,同時(shí)四大組件分工明確,共同構(gòu)成了可重用二蓝、靈活誉券、低耦合的安卓系統(tǒng)。四大組件必須在AndroidManifest文件中進(jìn)行注冊(cè)才能使用刊愚,接下來(lái)說(shuō)一下四大組件分別是什么以及他們的使用場(chǎng)景踊跟。
- Activity
基本概念:Activity是一個(gè)應(yīng)用組件,持有一個(gè)Window窗口用于繪制和展示界面鸥诽,接收和處理用戶操作
使用場(chǎng)景:主要負(fù)責(zé)與用戶進(jìn)行交互商玫,展示頁(yè)面給用戶并能接收和處理用戶的點(diǎn)擊,滑動(dòng)等操作事件并對(duì)用戶操作做出相應(yīng)的反饋 - Service
基本概念:Service相對(duì)于Activity沒(méi)有相應(yīng)的頁(yè)面牡借,生命周期較長(zhǎng)拳昌,執(zhí)行那些不需要和用戶交互但需要長(zhǎng)期運(yùn)行 的任務(wù)
使用場(chǎng)景:執(zhí)行不需要與用戶進(jìn)行交互的任務(wù),比如播放音樂(lè)等钠龙,用戶在聽歌曲的時(shí)候可以做其他操作提高了用戶體驗(yàn) - BroadcastReceiver
基本概念:BroadcastReceiver是一種消息型組件炬藤,用于在不同組件乃至不同應(yīng)用之間傳遞消息。進(jìn)行系統(tǒng)級(jí)別的消息通知碴里,Android應(yīng)用采用沙盒機(jī)制沈矿,不同應(yīng)用之間相互隔離開來(lái)不能直接相互訪問(wèn)資源,而廣播則提供了一種應(yīng)用內(nèi)組件間以及不同應(yīng)用之間通信的方式
使用場(chǎng)景:通過(guò)注冊(cè)相應(yīng)廣播我們可以監(jiān)聽系統(tǒng)啟動(dòng)廣播實(shí)現(xiàn)應(yīng)用開機(jī)啟動(dòng)功能咬腋,監(jiān)聽wifi羹膳,數(shù)據(jù)等狀態(tài)信息實(shí)現(xiàn)我們相應(yīng)的功能,一個(gè)頁(yè)面如果要對(duì)其他頁(yè)面的動(dòng)作做出相應(yīng)反饋我們也可以通過(guò)自定義廣播的方式作出相應(yīng)的處理從而降低不同頁(yè)面和組件間的耦合根竿。 - ContentProvider
基本概念:Android采用了沙箱機(jī)制陵像,可以保證各個(gè)應(yīng)用程序相對(duì)獨(dú)立和安全,可以免受其他應(yīng)用程序的惡意修改和攻擊保證數(shù)據(jù)的安全性寇壳,但是現(xiàn)實(shí)中不可能所有應(yīng)用完全獨(dú)立的醒颖,有時(shí)候就需要使用到其他應(yīng)用提供的數(shù)據(jù)比如QQ獲取我們的聯(lián)系人信息就涉及到QQ和通訊錄兩應(yīng)用間的數(shù)據(jù)共享,ContentProvider能夠便利的向其他應(yīng)用提供一個(gè)訪問(wèn)本應(yīng)用數(shù)據(jù)的接口九巡,還可以選擇只對(duì)哪一部分?jǐn)?shù)據(jù)進(jìn)行共享图贸,從而保證程序中的隱私數(shù)據(jù)不會(huì)有泄漏風(fēng)險(xiǎn)。
使用場(chǎng)景:第三方應(yīng)用讀取聯(lián)系人,日歷和短信等信息疏日,同時(shí)我們也可以給自己的應(yīng)用定義一系列操作通過(guò)ContentProvider提供給其他應(yīng)用程序使用偿洁。
二,Activity詳細(xì)介紹
- Activity生命周期
- 任務(wù)沟优,任務(wù)棧
- 啟動(dòng)模式
- 進(jìn)程和生命周期
1涕滋, Activity生命周期
由圖可以清楚的看到Activity在不同的情況下會(huì)走不同的生命周期,常見的生命周期有哪些呢侵俗?
一般情況生命周期
onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()從Activity A 跳轉(zhuǎn)到Activity B所經(jīng)歷的生命周期
Activity A onPause() -> Activity B onCreate() -> Activity B onStart() ->Activity B onResume() -> Activity A onStop()
按下返回鍵:Activity B onPause() -> Activity A onRestart() -> Activity A onStart() -> Activity A onResume() -> Activity B onStop() -> Activity B onDestroy()
注意:由此可見Activity A進(jìn)入 Activity B時(shí)會(huì)先執(zhí)行Activity A的onPause()方法锨用,如果我們?cè)诖朔椒ㄖ凶隽舜罅繌?fù)雜或者資源釋放工作會(huì)導(dǎo)致頁(yè)面跳轉(zhuǎn)出現(xiàn)延遲效果,造成不好的用戶體驗(yàn)隘谣。當(dāng)前Activity彈出Dialog彈窗不走生命周期
啟動(dòng)一個(gè)主題為Dialog樣式的Activity
Activity A onPause() -> Activity B onCreate() -> Activity B onStart() -> Activity B onResume()
點(diǎn)擊返回:Activity B onPause() -> Activity A onResume() ->Activity B onStop() -> Activity B onDestroy()如果當(dāng)前Activity啟動(dòng)模式為SingleTop增拥,啟動(dòng)自身頁(yè)面時(shí)生命周期
onPause() -> onNewIntent() -> onResume()橫豎屏切換時(shí)的生命周期
未配置configChanges屬性:會(huì)調(diào)用一個(gè)參數(shù)的onSaveInstanceState方法和onRestoreInstanceState()方法
生命周期為: onPause() -> onSaveInstanceState() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume()
配置configChanges屬性時(shí):不調(diào)用任何生命周期方法 android:configChanges="orientation|screenSize|keyboardHidden"什么情況下Activity只走onPause() 不走onStop()?
當(dāng)啟動(dòng)一個(gè)Theme為Dialog的Activity時(shí),只會(huì)執(zhí)行onPause() 點(diǎn)擊返回時(shí)執(zhí)行onResume()什么情況導(dǎo)致Activity的onDestroy() 方法不執(zhí)行寻歧?
外部強(qiáng)制關(guān)閉進(jìn)程或異常奔潰的時(shí)候
生命周期長(zhǎng)的對(duì)象持有當(dāng)前Activity的引用handler比較多
Activity被收集內(nèi)存強(qiáng)制回收是不會(huì)調(diào)用destroy方法的
2掌栅,任務(wù)任務(wù)棧
任務(wù):用戶在執(zhí)行某項(xiàng)任務(wù)時(shí)與之交互的一系列Activity集合
返回棧:執(zhí)行某項(xiàng)任務(wù)時(shí)用到的Activity會(huì)按照打開的順序排列在一個(gè)返回堆棧中,當(dāng)用戶一直按返回按鈕码泛,Activity會(huì)從堆棧中按照后進(jìn)先出的順序退出知道返回主屏幕猾封。移除堆棧中的所有Activity后,該任務(wù)將不復(fù)存在噪珊。
任務(wù)是一個(gè)整體單元晌缘,當(dāng)用戶開始一個(gè)新的任務(wù)或者通過(guò)主屏幕按鈕進(jìn)入主屏幕時(shí),任務(wù)可移至后臺(tái)痢站,當(dāng)前任務(wù)失去焦點(diǎn)枚钓,舉例來(lái)說(shuō),假設(shè)當(dāng)前任務(wù)(任務(wù) A)的堆棧中有 3 個(gè) Activity瑟押,當(dāng)前 Activity 下有 2 個(gè) Activity。用戶按主屏幕按鈕星掰,然后從應(yīng)用啟動(dòng)器中啟動(dòng)新應(yīng)用多望。主屏幕出現(xiàn)后,任務(wù) A 轉(zhuǎn)到后臺(tái)氢烘。當(dāng)新應(yīng)用啟動(dòng)時(shí)怀偷,系統(tǒng)會(huì)啟動(dòng)該應(yīng)用的任務(wù)(任務(wù) B),該任務(wù)具有自己的 Activity 堆棧播玖。與該應(yīng)用互動(dòng)后椎工,用戶再次返回到主屏幕并選擇最初啟動(dòng)任務(wù) A 的應(yīng)用。現(xiàn)在,任務(wù) A 進(jìn)入前臺(tái)维蒙,其堆棧中的所有三個(gè) Activity 都完好如初掰吕,堆棧頂部的 Activity 恢復(fù)運(yùn)行。此時(shí)颅痊,用戶仍可通過(guò)以下方式切換到任務(wù) B:轉(zhuǎn)到主屏幕并選擇啟動(dòng)該任務(wù)的應(yīng)用圖標(biāo)殖熟。
思考一個(gè)問(wèn)題,Android管理任務(wù)和返回棧的方式是將所有接連啟動(dòng)的Activity放到同一任務(wù)和一個(gè)“后進(jìn)先出”堆棧中斑响,大多數(shù)應(yīng)用頁(yè)面的跳轉(zhuǎn)都符合這種情況菱属,但有些場(chǎng)景這種方式卻不太適合,比如一個(gè)新聞列表頁(yè)面舰罚,點(diǎn)擊某個(gè)條目會(huì)進(jìn)入詳情顯示頁(yè)面纽门,但有時(shí)點(diǎn)擊沒(méi)反應(yīng)會(huì)多點(diǎn)擊幾次這樣會(huì)導(dǎo)致詳情頁(yè)面打開多個(gè),返回棧中存在了多個(gè)相同的詳情頁(yè)Activity营罢,這個(gè)時(shí)候當(dāng)我們點(diǎn)擊退出時(shí)需要點(diǎn)擊關(guān)閉詳情頁(yè)多次赏陵。再例如我們可能在多個(gè)應(yīng)用中需要獲取驗(yàn)證碼,如果使用目前的管理模式短信詳情頁(yè)會(huì)被打開多次愤钾,使用特別混亂瘟滨,因此就需要我們對(duì)任務(wù)和任務(wù)棧進(jìn)行管理,這就用到了Android提供的啟動(dòng)模式能颁。
3杂瘸,啟動(dòng)模式
Android的啟動(dòng)模式可以指定Activity的啟動(dòng)方式,Activity啟動(dòng)模式有四種分別為"standard"(默認(rèn)模式)伙菊,"singleTop"败玉,"singleTask","singleInstance“镜硕。
standard:
每次啟動(dòng)Activity都會(huì)創(chuàng)建新的Activity實(shí)例运翼,無(wú)論所在回退棧里是否已經(jīng)存在,每個(gè)實(shí)例可以屬于不同任務(wù)兴枯,一個(gè)任務(wù)也可以有多個(gè)實(shí)例血淌。
singleTop:
棧頂復(fù)用模式,如果要啟動(dòng)的Activity已經(jīng)存在當(dāng)前回退棧棧頂财剖,則會(huì)直接利用已有的Activity而不會(huì)再重新創(chuàng)建新的Activity實(shí)例悠夯。
singleTask:
棧內(nèi)復(fù)用模式,如果要啟動(dòng)的Activity已經(jīng)存在于回退棧中躺坟,無(wú)論它是否在棧頂都不會(huì)重新創(chuàng)建新實(shí)例沦补,啟動(dòng)此Activity會(huì)彈出此Activity之上的所有其他Activity從而使此Activity位于回退棧棧頂,直接使用咪橙。
singleInstance:
單例復(fù)用模式夕膀,使用了此模式的Activity單獨(dú)使用一個(gè)回退棧虚倒,此Activity啟動(dòng)的其他Activity不會(huì)包含在此回退棧。
指定Activity以那種模式啟動(dòng)有兩種方式:通過(guò)Intent標(biāo)記和清單文件中使用 <activity>元素的 launchMode屬性指定
launchMode屬性指定:直接將launchMode值設(shè)置為standard或singleTop或singleTask或singleInstance
Intent標(biāo)記:?jiǎn)?dòng) Activity 時(shí)产舞,您可以在傳送給 startActivity() 的 intent 中添加相應(yīng)的標(biāo)記來(lái)修改 Activity 與其任務(wù)的默認(rèn)關(guān)聯(lián)魂奥,intent標(biāo)記包含F(xiàn)LAG_ACTIVITY_NEW_TASK,F(xiàn)LAG_ACTIVITY_SINGLE_TOP庞瘸,F(xiàn)LAG_ACTIVITY_CLEAR_TOP
三種捧弃。
FLAG_ACTIVITY_NEW_TASK:效果相當(dāng)于singleTask。
FLAG_ACTIVITY_SINGLE_TOP:效果相當(dāng)于singleTop擦囊。
FLAG_ACTIVITY_CLEAR_TOP:如果要啟動(dòng)的 Activity 已經(jīng)在當(dāng)前任務(wù)中運(yùn)行违霞,則不會(huì)啟動(dòng)該 Activity 的新實(shí)例,而是會(huì)銷毀位于它之上的所有其他 Activity瞬场,并通過(guò)onNewIntent()將此 intent 傳送給它的已恢復(fù)實(shí)例(現(xiàn)在位于堆棧頂部)launchMode 屬性沒(méi)有可產(chǎn)生此行為的值买鸽。
清除返回堆棧
如果用戶離開任務(wù)較長(zhǎng)時(shí)間,系統(tǒng)會(huì)清除任務(wù)中除根 Activity 以外的所有 Activity贯被。當(dāng)用戶再次返回到該任務(wù)時(shí)眼五,只有根 Activity 會(huì)恢復(fù)。系統(tǒng)之所以采取這種行為方式是因?yàn)橥睿?jīng)過(guò)一段時(shí)間后看幼,用戶可能已經(jīng)放棄了之前執(zhí)行的操作,現(xiàn)在返回任務(wù)是為了開始某項(xiàng)新的操作幌陕。
您可以使用一些 Activity 屬性來(lái)修改此行為:
alwaysRetainTaskState:如果在任務(wù)的根 Activity 中將該屬性設(shè)為 "true"诵姜,則不會(huì)發(fā)生上述默認(rèn)行為。即使經(jīng)過(guò)很長(zhǎng)一段時(shí)間后搏熄,任務(wù)仍會(huì)在其堆棧中保留所有 Activity棚唆。
clearTaskOnLaunch:如果在任務(wù)的根 Activity 中將該屬性設(shè)為 "true",那么只要用戶離開任務(wù)再返回心例,堆棧就會(huì)被清除到只剩根 Activity宵凌。也就是說(shuō),它與 alwaysRetainTaskState正好相反止后。用戶始終會(huì)返回到任務(wù)的初始狀態(tài)瞎惫,即便只是短暫離開任務(wù)也是如此。
finishOnTaskLaunch:該屬性與 clearTaskOnLaunch類似译株,但它只會(huì)作用于單個(gè) Activity 而非整個(gè)任務(wù)微饥。它還可導(dǎo)致任何 Activity 消失,包括根 Activity古戴。如果將該屬性設(shè)為 "true"
,則 Activity 僅在當(dāng)前會(huì)話中歸屬于任務(wù)矩肩。如果用戶離開任務(wù)再返回现恼,則該任務(wù)將不再存在肃续。
4,進(jìn)程和生命周期
Android系統(tǒng)為了在系統(tǒng)內(nèi)存不足的時(shí)候應(yīng)該終止那些進(jìn)程叉袍,Android會(huì)根據(jù)每個(gè)進(jìn)程中運(yùn)行的組件以及組件狀態(tài)始锚,將他們放入”重要性層次結(jié)構(gòu)“,這些層次結(jié)構(gòu)包含以下五種喳逛。
前臺(tái)進(jìn)程:當(dāng)前正在與用戶交互的Activity所在的進(jìn)程
可見進(jìn)程:Activity可見但沒(méi)有在前臺(tái)所在的進(jìn)程
服務(wù)進(jìn)程:Activity在后臺(tái)開啟了Service服務(wù)所在的進(jìn)程
后臺(tái)進(jìn)程:Activity完全處于后臺(tái)所在的進(jìn)程
空進(jìn)程:沒(méi)有任何Activity存在的進(jìn)程優(yōu)先級(jí)最低
系統(tǒng)內(nèi)存資源不足是回收順序?yàn)椋嚎者M(jìn)程->后臺(tái)進(jìn)程->服務(wù)進(jìn)程->可見進(jìn)程->前臺(tái)進(jìn)程瞧捌。