Activity相關(guān)
- 如果新打開的Activity采用了透明主題,那么當(dāng)前Activity不會(huì)回調(diào)onStop
- Activity A打開Activity B,那么這時(shí),A的onPause先執(zhí)行,然后B的onCreate onStart onResume才會(huì)執(zhí)行。
- Activity的onPause中不能做重量級操作,由于上面原因,盡量都放到onStop中。
- 源碼角度Activity的大致啟動(dòng)流程:
Activity的啟動(dòng)過程相當(dāng)復(fù)雜,涉及Instrumentation,ActivityThread,ActivityManageService(AMS)
簡單步驟:啟動(dòng)Activity的請求由Instrumentation來處理,它會(huì)通過Binder向AMS發(fā)送請求,AMS內(nèi)部維護(hù)著一個(gè)ActivityStack并負(fù)責(zé)棧內(nèi)Activity的狀態(tài)同步,AMS通過ActivityThread去同步Activity的狀態(tài)從而完成生命周期方法的調(diào)用,ActivityThread內(nèi)部通過ApplicationThread的scheduleLaunchActivity(通過Handler來執(zhí)行)來完成新Activity的onCreate,onStart,onResume。
- Activity在異常終止的情況下,系統(tǒng)會(huì)調(diào)用onSaveInstanceState來保存當(dāng)前狀態(tài),當(dāng)Activity被重新創(chuàng)建后,系統(tǒng)又會(huì)調(diào)用onRestoreInstanceState和onCreate來恢復(fù)保存的數(shù)據(jù)。
onSaveInstanceState調(diào)用時(shí)機(jī):onStop之前,但和onPause沒有順序關(guān)系,可能在前,可能在后。
onRestoreInstanceState調(diào)用時(shí)機(jī):onStart之后。
- 在onSaveInstanceState和onRestoreInstanceState中系統(tǒng)為我們做了些恢復(fù)工作,比如保存當(dāng)前Activiy的視圖結(jié)構(gòu),并恢復(fù),比如文本框中的文字等。
- 每個(gè)View都有onSaveInstanceState和onRestoreInstanceState,比如TextView,源碼中已經(jīng)重新了兩個(gè)方法,用于保存與恢復(fù)TextView的當(dāng)前狀態(tài)。
關(guān)于保存與恢復(fù)View的層次結(jié)構(gòu)流程:首先,Activity被異常終止時(shí),Activity會(huì)調(diào)用onSaveInstanceState,然后Activity會(huì)委托Window去保存數(shù)據(jù),接著,Window會(huì)委托頂層容器DecroView(一個(gè)ViewGroup)去保存數(shù)據(jù),從而一層層通知子View來保存數(shù)據(jù)。
- 委托模式:Acitivity的狀態(tài)保存與恢復(fù),事件的攔截與分發(fā),View的繪制過程都用到過。
- 當(dāng)指定Activity節(jié)點(diǎn)的configChanges屬性后,會(huì)回調(diào)Activity的OnConfigurationChanged方法,configChanges的值會(huì)傳入到OnConfigurationChanged中
當(dāng)指定android:configChanges='orientation|screenSize'時(shí),切換屏幕方向,不會(huì)重新走生命周期,而是會(huì)調(diào)用OnConfigurationChanged
- TaskAffinity : 標(biāo)識(shí)Activity所需要的任務(wù)棧名字,默認(rèn)情況下為包名,可以為每個(gè)Activity設(shè)置單獨(dú)的TaskAffinity屬性,不能和包名相同,TaskAffinity主要和SingleTask啟動(dòng)模式或者allowTaskPreparening配對使用才有意義
TaskAffinity和allowTaskPreparening一起使用時(shí):應(yīng)用A啟動(dòng)應(yīng)用B的某個(gè)Activity,如果這個(gè)Activity的allowTaskPreparening為true,那么當(dāng)啟動(dòng)B應(yīng)用時(shí),此Activity會(huì)直接從A的任務(wù)棧轉(zhuǎn)移到B的任務(wù)棧。(P19)
- 通過Intent設(shè)置的啟動(dòng)模式優(yōu)先級高于manifest文件中設(shè)置的啟動(dòng)模式
- 任務(wù)棧分為前臺(tái)任務(wù)棧和后臺(tái)任務(wù)棧,后臺(tái)任務(wù)棧中的Activity都屬于暫停狀態(tài),用戶可以通過切換將后臺(tái)任務(wù)棧再次調(diào)用到前臺(tái)來。
- Activity的Flags
FLAG_ACTIVITY_NEW_TASK一般與FLAG_ACTIVITY_CLEAR_TOP配合使用,這樣,如果被啟動(dòng)的Activity實(shí)例已經(jīng)存在,則移除它頂部的Activity,調(diào)用它的onNewIntent方法
- Activity的隱式調(diào)用與顯式調(diào)用,顯式調(diào)用優(yōu)先,
隱式調(diào)用需要Intent能夠匹配目標(biāo)組件的IntentFilter中所設(shè)置的過濾條件
IntentFilter中的過濾條件有action,category,data,
需要同時(shí)匹配上面三個(gè)條件,一個(gè)過濾列表中可以有多個(gè)action,category,data
一個(gè)Activity可以設(shè)置多個(gè)IntentFilter,一個(gè)Intent只要匹配任何一個(gè)IntentFilter即可成功啟動(dòng)Activiity.
Action
為字符串,區(qū)分大小寫,一個(gè)Intent中設(shè)置的action只要與過濾規(guī)則中的任何一個(gè)action匹配則算是匹配成功
Category
為字符串,可以不設(shè),不設(shè)置默認(rèn)匹配成功,不設(shè)置為android.intent.category.DEFALUT,設(shè)置了后,不管設(shè)置幾個(gè),都必須與過濾條件中的其中一個(gè)匹配,否則匹配失敗。
data
與action類似,如果過濾規(guī)則中定義了data,那么intent中也要定義可匹配的data,data的語法參考 p31
- 隱式啟動(dòng)Activity時(shí)可以做判斷,因?yàn)闀?huì)報(bào)錯(cuò),可以通過PackageManeger的resolveActivity方法或Intent的resolveActivity方法來判斷,如果找不到則返回null
也可以采用PackageManager提供的queryAllActivies方法,它不是返回一個(gè)最佳匹配的Activity,而是返回所有匹配的activity的集合,第二個(gè)參數(shù)需要傳入MATCH_DEFALUT_ONLY