Android開發藝術探索之讀書筆記一

第一章?? Activity的生命周期和啟動模式

書中作者大體上從兩種情況來介紹了Activity的生命周期。第一種是手機運行環境良好不變(屏幕方向不變、內存充足等),用戶正常操作APP頁面。第二種情況是異常情況下,Activity的生命周期受到了運行環境改變的影響,被系統殺死,Activity的生命周期發生了改變。

在第一種情況中,Activity的生命周期大致如下:

系統調用Activity的onCreate方法創建一個Activity對象,隨后調用onStart方法,這時候Activity其實就是可見狀態,但還不是可交互狀態,接下來會調用onResume方法將其作為前臺活動頁面,此時Activity的狀態是可交互狀態,此過程對應的是圖一中的綠色箭頭所顯示的流程。

當出現頁面部分被遮擋從而使用戶無法與此Activity進行交互時(如:頁面中彈出了對話框遮擋住了Activity),Activity的onPause方法就會被調用。如果對話框消失,Activity重新回到前臺狀態(可交互狀態),那么onResume方法會重新被調用。此過程是圖一中藍色箭頭所顯示的流程。

如果Activity A正處于可交互狀態,此時頁面跳轉到另一個頁面Activity B,生命周期函數會依次被調用:Activity A 的onPause----Activity B 的onCreate-------Activity B的onStart------Activity B 的onResume-------Activity A 的onStop。當頁面再次回到Activity A的時候,會調用Activity B的onPause-----------Activity A的onRestart-------Activity A的 onStart--------Activity A 的onResume------Activity B的onStop。此過程是圖一紫色箭頭所顯示的流程。

在第二種情況中,也分兩種異常情況。

第一種異常情況是指與資源相關的系統配置發生變化,如將手機語言進行更改,或者是手機的屏幕方向發生了改變,都會使Activity被重新創建加載,除非Activity中configChanges屬性配置了對應的值。在異常情況下,Activity發生被回收重新創建,其onPause、onStop、onDestory方法均被調用。同時在調用onStop方法之前還調用了另一個方法onSaveInstanceState方法將頁面的狀態進行保存(至于如何對Activity狀態進行保存就需要去閱讀相關源碼才知道,不過書中提到系統是運用了委托機制來進行狀態的保存)。在該Activity再次被創建時,系統會調用onRestoreInstanceState方法,并將onSaveInstanceState方法中保存的Bundle對象來作為參數傳遞給onRestoreInstanceState方法,此過程如圖二所示。

第二種異常情況,當手機運行內存不足會導致優先級別較低的Activity所在的進行被殺死。Activity按照優先級別從高到低可以分為:前臺交互的Activity優先級別最高、其次是可見但無法交互的Activity、最低級別是處于系統后臺被暫停的Activity。在手機內存不足的情況下,系統會優先殺死優先級別低的Activity所在進程。同樣的,在此過程中Activity的生命周期跟第一種異常情況是一樣的,此過程如圖一紅色箭頭所示。


Activity的啟動模式

書中分別介紹了Activity的四種加載模式:standard、singleTop、singleTask、singleInstance。

第一種加載方式相對容易理解,在標準模式下啟動,被啟動的Activity將會加載到啟動它的Activity所在的任務棧中,所以如果被加載的Activity不是由Activity的context來啟動加載的,那么就會報錯,書中舉了ApplicationContext通過標準模式下加載Activity就會報異常這個例子。此模式下Activity如果多次被加載,會出現多個實例。

第二種加載模式singleTop是指棧頂復用。意思就是如果Activity的實例是位于棧頂,再次以棧內復用的方式加載的話,該Activity不會被重新創建出新的實例,而是重復利用已經位于棧頂的實例,所以被重用的實例都會在被重新調用的時候加載它的onNewIntent方法。如果將要被啟動的Activity的實例不是位于棧頂,那么還是會被重新創建新的實例。

第三種Activity加載方式singleTask是指棧內復用。棧內復用是指Activity實例所需要的任務棧中已經存在一個將要被加載的Activity的實例,那么該實例將會被復用。同時,如果實例被重用,所有位于該實例頂的實例都會被清出該任務棧,符合clearTop原則。跟singleTask配合使用的還有一個Activity的屬性,TaskAffinity。該屬性可以指定加載的Activity到哪個任務棧。默認情況下所有的Activity都是加載都以包名相同的任務棧中。

第四種加載模式singleInstance。這是一種比較少用到的模式,在全局中單例模式。意思就是在整個應用中,如果某個Activity以這種方式加載啟動,那么系統會新創建一個任務棧,并且創建一個Activity的實例入棧。

學完這四種加載模式后,我最后有一個疑問,如果說在標準模式下啟動,被啟動的Activity將會加載到啟動它的Activity所在的任務棧中,那如果從頁面MainActivity標準方式跳轉到SecondActivity,再通過SinlgeInstance方式加載SingleInstanceActivity,最后在SingleInstanceActivity中通過標準的加載方式加載ThirdActivity,那么ThirdActivity會不會跟SingleInstanceActivity在同一個任務棧中呢?

下圖為我自己驗證一個過程的結果:

顯然ThirdActivity不跟SingleInstanceActivity在同一個任務棧,而是在默認的任務棧中。

最后談到了設置Activity加載模式的方法有兩種,一種是通過清單文件來設置,另外一種是通過Java代碼中啟動跳轉的時候設置標示位來實現,兩種方式的區別不是很大,但第一種方式無法設置FLAG_ACTIVITY_CLEAR_TOP標識,第二種方法無法為Activity設置singleInstance模式,并且如果兩種方式都設置了,那么以第二種方式為主。

Activity的Flags

這部分內容比較少使用到,正常情況下都不需要指定Activity的Flags。書中主要介紹了常見的幾種標識:

FLAG_ACTIVITY_NEW_TASK??? =====作用等同于啟動模式中的singleTask模式

FLAG_ACTIVITY_SINGLE_TOP======作用等同于啟動模式中的singleTop模式

FLAG_ACTIVITY_CLEAR_TOP?? ======該標識需要FLAG_ACTIVITY_NEW_TASK配合使用。將目標Activity實例所在任務棧中位于該實例上面的所有Activity都被清空退出棧內。意味中singleTask模式就具有FLAG_ACTIVITY_CLEAR_TOP標識

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS=======具有該標識的Activity不會出現歷史Activity列表中。該標識等同于Activity屬性android:excludeFromRecents=true


IntentFilter的匹配規則

啟動Activity的方式包括了顯式和隱式,顯示啟動相對簡單,這里主要是講解如何通過IntentFilter的匹配來隱式啟動Activity。在清單文件中,Activity標簽中可以包含多個IntentFilter匹配規則。每個匹配規則中都是由action、category、data三個標簽來定義規則。只有完全匹配到某一個IntentFilter,才會啟動對應的Activity。如何才算完全匹配到呢?在IntentFilter中的所定義的屬性都分別滿足相應的action、category、data的匹配規則。

1)action的匹配規則:

action的字符串值必須完全一樣,區分字母的大小寫。如果一個IntentFilter中定義了多個action,intent必須滿足其中一個。

2)category的匹配規則:

所有隱式啟動Activity都會自動在intent中加入了category值為:android.intent.category.DEFAULT。所以在IntentFilter中必須定義

由于所有的隱式啟動都會自動加入category,所以可以設置intent的category,也可以不設置。但是如果intent中設置了category,那么就必須跟IntentFilter中的有匹配。

3)data的匹配規則:

data匹配分兩部分,mimeType和URI。

mimeType指媒體類型,

而URI包含的字段有:scheme、host、port、path、pathPattern、pathPrefix

data中如果沒有設置scheme的值,默認是content或者file。

如果IntentFilter中設置了data,那么intent中就必須設置data并且跟其中某一個data。這里匹配成功是指過濾條件中的部分data出現在Intent中的data。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容