筆記來源:任玉剛《Android開發(fā)藝術(shù)探索》
一. Activity生命周期切換
二. 正常情況下的生命周期分析
2.1.onStart和onResume留凭,onPause和onStop的區(qū)別
onStart和onStop是從Activity 這個(gè)角度來回調(diào)的。
onResume和onPause是從Activity 這個(gè)角度來回調(diào)的。
onStart的時(shí)候党窜,Activity可見但還在后臺(tái)(我們看不到)屉佳,onResume的時(shí)候Activity才顯示在前臺(tái)
2.2. 當(dāng)前Activity為A窃判,此時(shí)用戶打開一個(gè)新ActivityB,那么A的onPause和B的onResume哪個(gè)先執(zhí)行蜈亩?
必須A的onPause執(zhí)行完成以后,ActivityB才能啟動(dòng)
三. 異常情況下的生命周期分析
如橫豎屏切換前翎,默認(rèn)情況下稚配,Activity會(huì)被銷毀并重新創(chuàng)建,非默認(rèn)情況下港华,可以阻止系統(tǒng)重新創(chuàng)建Activity
3.1. 用來保存當(dāng)前Activity的狀態(tài)道川,用來恢復(fù)。系統(tǒng)才會(huì)調(diào)用這兩個(gè)方法,其他情況不會(huì)觸發(fā)該過程
3.2 onSaveInstanceState在onStop之前調(diào)用冒萄,和onPause無時(shí)序關(guān)系臊岸。onRestoreInstanceState在onStart之后調(diào)用
3.3 當(dāng)AndroidMainfest.xml文件給Activity設(shè)置android:configChanges="orientation|screenSize|keyboardHidden"時(shí),Activity異常中止時(shí)不會(huì)重建Activity尊流,onSaveInstanceState和onRestoreInstanceState不會(huì)被調(diào)用帅戒,取而代之的是調(diào)用了onConfigurationChanged方法
四. Activity的啟動(dòng)模式
4.1
每次啟動(dòng)一個(gè)Activity都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例崖技,不管這個(gè)實(shí)例是否已經(jīng)存在逻住。誰啟動(dòng)新Activity,新Activity就運(yùn)行在啟動(dòng)它的那個(gè)Activity的棧中
4.2
如果新Activity已經(jīng)位于任務(wù)棧的棧頂瞎访,那么此Activity不會(huì)被重建,onCreate吁恍,onStart不會(huì)被調(diào)用装诡,其onNewIntent方法會(huì)被回調(diào)。如果棧內(nèi)為ABCD四個(gè)棧頂践盼,A位于棧底鸦采,D位于棧頂,再次啟動(dòng)D咕幻,如果D啟動(dòng)模式為singleTop渔伯,棧內(nèi)仍為ABCD,如果D是standard肄程,棧內(nèi)則為ABCDD
4.3
只要Activity在一個(gè)棧中存在,那么在該棧中就不會(huì)重新創(chuàng)建實(shí)例蓝厌,和singleTop一樣也會(huì)回調(diào)其onNewIntent玄叠。當(dāng)具有singleTask模式的Activity A請(qǐng)求啟動(dòng)后,系統(tǒng)首先會(huì)尋找是否存在A想要的任務(wù)棧拓提,如果不存在读恃,就重新創(chuàng)建一個(gè)任務(wù)棧,然后創(chuàng)建A的實(shí)例后把A放到棧中代态。如果存在A所需的任務(wù)棧寺惫,這時(shí)看A是否在棧中有實(shí)例存在,如果有蹦疑,就會(huì)把A調(diào)到棧頂并調(diào)用onNewIntent方法西雀,如果實(shí)例不存在,就創(chuàng)建A的實(shí)例并把A壓入棧中歉摧。
4.3
加強(qiáng)的singTask模式腔呜,除了具備singleTask模式的所有特性之外,具有此種模式的Activity只能單獨(dú)地位于一個(gè)任務(wù)棧中
任務(wù)棧:TaskAffinity
- 該參數(shù)標(biāo)識(shí)了一個(gè)Activity所需要的任務(wù)棧的名字再悼,默認(rèn)情況下核畴,所有Activity所需的任務(wù)棧的名字為應(yīng)用的包名。
- 我們也可以為每個(gè)Activity都單獨(dú)指定TaskAffinity屬性帮哈,但屬性值必須不能和包名相同膛檀,否則相當(dāng)于沒有指定。
- TaskAffinity屬性主要和singleTask啟動(dòng)模式或者allowTaskReparenting屬性配對(duì)使用娘侍,在其他情況下沒有意義
- 任務(wù)棧分為前臺(tái)任務(wù)棧和后臺(tái)任務(wù)棧咖刃,后臺(tái)任務(wù)棧中的Activity位于暫停狀態(tài),用戶可以通過切換后臺(tái)任務(wù)棧再次調(diào)到前臺(tái)
- TaskAffinity和allowTaskReparenting結(jié)合時(shí)憾筏。有A和B兩個(gè)應(yīng)用嚎杨,A啟動(dòng)了B的一個(gè)Activity C,然后按Home鍵回到桌面氧腰,再點(diǎn)擊B的桌面圖標(biāo)枫浙,這個(gè)時(shí)候并不是啟動(dòng)了B的主Activity,二是重新顯示了被應(yīng)用A啟動(dòng)的Activity C古拴。即C從A的任務(wù)棧轉(zhuǎn)移到了B的任務(wù)棧中箩帚。
TaskAffinity使用: 通過AndroidMainfest為Activity指定任務(wù)棧 android:taskAffinity="taskName"
如何給Activity指定啟動(dòng)模式,兩種方法:
第一種通過AndroidMainfest為Activity指定啟動(dòng)模式黄痪,android:launchMode="singleTask"
第二種通過java代碼 Intent 中設(shè)置標(biāo)志位為Activity指定啟動(dòng)模式 Intent intent = new Intent(A.this,B.class) ;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
第二種優(yōu)先級(jí)高于第一種紧帕,若兩種同時(shí)存在,以第二種為準(zhǔn)
五. IntentFilter的匹配規(guī)則
相關(guān)文章:https://blog.csdn.net/xiaohanluo/article/details/52637520
啟動(dòng)Activity分為兩種桅打,顯示調(diào)用和隱式調(diào)用是嗜。顯示調(diào)用即需要明確指定被啟動(dòng)對(duì)象的組件信息,包括包名和類名挺尾,而隱式調(diào)用則不需要明確指定組件信息鹅搪。如果一個(gè)Intent既是顯示又是隱式則以顯式調(diào)用為主。
隱式調(diào)用需要Intent能夠匹配目標(biāo)組件的IntentFilter中設(shè)置的過濾信息action遭铺,category丽柿,data。
一個(gè)過濾列表intent-filter中的action掂僵,category航厚,data可以有多個(gè),所有的action锰蓬,category,data分別構(gòu)成不同類別眯漩。只有一個(gè)Intent同時(shí)匹配action類別芹扭,category類別麻顶,data類別才算完全匹配,只有完全匹配才能成功啟動(dòng)目標(biāo)Activity
一個(gè)Activity可以有多個(gè)intent-filter舱卡,一個(gè)Intent只要能匹配任何一組intent-filter即可成功啟動(dòng)對(duì)應(yīng)的Activity辅肾。
action的匹配規(guī)則:要求Intent中的action存在且必須和過濾規(guī)則中的其中一個(gè)action相同。actoin區(qū)分大小寫轮锥。
category匹配規(guī)則:系統(tǒng)在調(diào)用startActivity或者startActivityForResult的時(shí)候會(huì)默認(rèn)為Intent加上"android.intent.category.DEFAULT"這個(gè)category矫钓。
通過隱式調(diào)用方式啟動(dòng)一個(gè)Activity的時(shí)候,需要做一下判斷舍杜,看是否有Activity能夠匹配我們的隱式Intent新娜,如果不做判斷,當(dāng)沒有匹配的時(shí)候就會(huì)崩潰報(bào)錯(cuò)既绩。判斷的方式有兩種:采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法概龄,如果找不到匹配的Activity就會(huì)返回null。
不含有DEFAULT這個(gè)category的Activity是無法接收隱式Intent的饲握。
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
這兩者共同作用是用來標(biāo)明這是一個(gè)入口Activity并且會(huì)出現(xiàn)在系統(tǒng)的應(yīng)用列表中私杜,少了任何一個(gè)都沒有實(shí)際意義,也無法出現(xiàn)在系統(tǒng)的應(yīng)用列表中救欧,即二者缺一不可衰粹。
我們有時(shí)在一個(gè)應(yīng)用中,不小心給兩個(gè)以上的Activity添加了這兩個(gè)東西笆怠,我們就會(huì)發(fā)現(xiàn)桌面上就會(huì)有兩個(gè)以上該應(yīng)用的圖標(biāo)铝耻。