編輯:Android編程入門
Activity的完整生命周期如下圖:
Activity的加載模式有四種:
standard: 標准模式,默認的加載模式,每次通過這種模式啟動目標Acitivity,都創建一個新的實例,並將該Activity添加到當前棧中。
singleTop: 與標准模式類似,只有當Activity位於Task頂時,系統不會重新創建目標Activity的示例,而是直接復用已有的Activity實例。
singleTask:
如果要啟動的Activity不存在,系統創建Activity實例,並將它加入棧頂
如果將啟動的Activity存在,已經位於棧頂,此時與singleTop行為相同
如果要啟動的Activity存在,但不是位於棧頂,系統會使Activity上面所有的Activity出棧。
singleInstance:
如果要啟動的Activity不存在,系統會創建一個新的Task,再創建Activity實例,將它加入新Task的棧頂
如果要啟動的Activity存在,無論它在哪個應用程序中,系統都會把該Activity所在的Task轉至前台。
下面依次驗證,再四種加載模式下,Activity的各生命周期如何執行。假設有Activity A,B,C
1、標准模式啟動A->B->C
//啟動A D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume //啟動B D/activityA(19864): onPause D/activityB(19864): onCreate D/activityB(19864): onStart D/activityB(19864): onResume D/activityA(19864): onStop //啟動C D/activityB(19864): onPause D/activityC(19864): onCreate D/activityC(19864): onStart D/activityC(19864): onResume D/activityB(19864): onStop
然後按返回建:
D/activityC(19864): onPause D/activityB(19864): onRestart D/activityB(19864): onStart D/activityB(19864): onResume D/activityC(19864): onStop D/activityC(19864): onDestory
所以如果未調用onDestory重新啟動的話,不會調用onCreate,而是會調用onRestart。
2、A->B->A
D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume D/activityA(19864): onPause D/activityB(19864): onCreate D/activityB(19864): onStart D/activityB(19864): onResume D/activityA(19864): onStop D/activityB(19864): onPause D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume D/activityB(19864): onStop
修改A的啟動模式為singleTop
->A->A
D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityA(27075): onPause D/activityA(27075): onNewIntent D/activityA(27075): onResume
->A->B->A
D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityA(27075): onPause D/activityB(27075): onCreate D/activityB(27075): onStart D/activityB(27075): onResume D/activityA(27075): onStop D/activityB(27075): onPause D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityB(27075): onStop
當A不是棧頂時,啟動A,又重新創建了A,而且觀察以上輸出,兩個Activity切換時,首先當前Activity先onPause,然後被啟動的Activity,依次onCreate, onStart, onResume顯示出來之後,之前的Activity才會onStop。
修改A的啟動方式為singleTask,
->A->A
D/activityA( 2744): onCreate D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityA( 2744): onPause D/activityA( 2744): onNewIntent D/activityA( 2744): onResume
當A不存在時,創建A,當A存在且在棧頂時,先onPause,然後onNewIntent,之後onResume。
->A->B->A
D/activityA( 2744): onCreate D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityA( 2744): onPause D/activityB( 2744): onCreate D/activityB( 2744): onStart D/activityB( 2744): onResume D/activityA( 2744): onStop D/activityB( 2744): onPause D/activityA( 2744): onNewIntent D/activityA( 2744): onRestart D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityB( 2744): onStop D/activityB( 2744): onDestory
可以看到第二次啟動A後,A調用了onNewIntent,onRestart,onStart,onResume,關鍵是之後調了B的onStop, onDestory,在之前的兩種模式下只是另B,調用了onStop,所以推斷,singleTask時,是之前的A通過onNewIntent重新進入onResume,然後將B移除出了棧。
修改A的啟動方式為SingleInstance
->A->A
D/activityA(10578): onCreate D/activityA(10578): onStart D/activityA(10578): onResume D/activityA(10578): onPause D/activityA(10578): onNewIntent D/activityA(10578): onResume
與singleTask表現一致
->A->B->A
D/activityA(10578): onCreate D/activityA(10578): onStart D/activityA(10578): onResume D/activityA(10578): onPause D/activityB(10578): onCreate D/activityB(10578): onStart D/activityB(10578): onResume D/activityA(10578): onStop D/activityB(10578): onPause D/activityA(10578): onNewIntent D/activityA(10578): onRestart D/activityA(10578): onStart D/activityA(10578): onResume D/activityB(10578): onStop
在singleInstance模式下,復用了原來的A,對B只是onStop,並沒有發生出棧銷毀。
總結以上:
當復用一個已經存在的Activity時,通常是從它的onNewIntent或onRestart開始調起,
如果一個Activity要出棧,必然會調到onDestory
在兩個Activity切換的過程中,是當前的Activity先onPause,然後讓新的Activity創建或者restart,知道onResume,前一個Activity才會走onStop以及onDestory
另外一個問題:分別在A生命周期函數內啟動B(A,B都是Standared),
D/activityA(17860): onCreate D/activityA(17860): onStart D/activityA(17860): onResume D/activityA(17860): onPause D/activityB(17860): onCreate D/activityB(17860): onStart D/activityB(17860): onResume D/activityA(17860): onStop
生命周期的回調函數是完整的,都會依次調到,但是有個問題是當按back鍵後,會出現如下:
D/activityB(19588): onPause D/activityA(19588): onRestart D/activityA(19588): onStart D/activityA(19588): onResume D/activityA(19588): onPause D/activityB(19588): onCreate D/activityB(19588): onStart D/activityB(19588): onResume D/activityB(19588): onStop D/activityB(19588): onDestory D/activityA(19588): onStop
需要返回A,但是A在啟動的生命周期中又啟動了B,這時的行為就跟啟動模式有關了,總是它正常切換時正確的執行順序。
這個知識點太繞了,其實萬變不離其宗,都是四種啟動模式生命周期執行順序的組合。
Android UI基礎之五大布局 Android的界面是有布局和組件協同完成的,布局好比是建築裡的框架,而組件則相當於建築裡的磚瓦。組件按照布局
前面幾節,我們重點討論了自定義View的三板斧,這節我們來討論自定義ViewGroup,為什麼要自定義ViewGroup,其實就是為了更好的管理View。 自定義Vie
requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().addFlags(WindowManager.Layo
一、ArrayAdapter 只顯示文字activitylistview_layout.xml<?xml version=1.0 encoding=utf-8?&g