Android開發(fā) - Activity的生命周期

Activity的生命周期很重要骤菠,掌握好Activity的生命周期畅厢,應用程序才會擁有好的用戶體驗

返回棧

Android的Activity是可以重疊的欲鹏。每啟動一個新的Activity暴凑,就會覆蓋在原Activity之上如绸,然后點擊Back鍵就會銷毀最上面的Activity完域,下面的Activity就會重新顯示出來软吐。

Android是使用任務(Task)來管理Activity的,一個任務就是一組放在棧里的Activity的集合吟税,這個棧也被稱作返回棧(Back stack)凹耙。棧是一種后進先出的數(shù)據(jù)結(jié)構(gòu)姿现,默認情況下,每當啟動了一個新的Activity肖抱,它會在返回棧中入棧备典,并處于棧頂位置。當按下Back鍵或調(diào)用finish()方法去銷毀一個Activity時意述,處于棧頂?shù)腁ctivity會出棧熊经,這時前一個入棧的Activity就會重新處于棧頂位置,系統(tǒng)就會顯示處于棧頂?shù)腁ctivity給用戶欲险。

返回棧示意圖.png

Activity狀態(tài)

每個Activity在其生命周期中最多可能會有4種狀態(tài)

  • 運行狀態(tài)

當一個Activity位于返回棧的棧頂時镐依,這時Activity就處于運行狀態(tài),系統(tǒng)最不愿意回收處于運行狀態(tài)的Activity天试,這會帶來很差的用戶體驗

  • 暫停狀態(tài)

當一個Activity不再處于棧頂位置槐壳,但仍然可見,這時Activity就進入了暫停狀態(tài)喜每。既然不在棧頂了务唐,那為什么還能可見呢?這是因為并不是每一個Activity都會占滿整個屏幕带兜,比如對話框形式的Activity只會占用屏幕中間的部分區(qū)域枫笛。處于暫停狀態(tài)的Activity仍然是完全存貨的,系統(tǒng)也不愿意回收這種Activity刚照,只有在內(nèi)存較低的情況下刑巧,系統(tǒng)才會去考慮回收這種Activity

  • 停止狀態(tài)

當一個Activity不在棧頂并且也完全不可見的時候,就進入了停止狀態(tài)无畔。系統(tǒng)仍然會為這種Activity保存相應的狀態(tài)和成員變量啊楚,但是這并不是完全可靠的,當其他地方需要內(nèi)存時浑彰,處于停止狀態(tài)的Activity有可能被系統(tǒng)回收

  • 銷毀狀態(tài)

當一個Activity從返回棧中移除后就變成了銷毀狀態(tài)恭理。系統(tǒng)最傾向于回收處于這種狀態(tài)的Activity,以保證手機的內(nèi)存充足

Activity的生存期

Activity類中定義了7個回調(diào)方法郭变,覆蓋了Activity生命周期的每個環(huán)節(jié)

  • onCreate().每個Activity中都需要重寫這個方法颜价,它會在Activity第一次創(chuàng)建的時候調(diào)用。應該在這個方法中完成Activity的初始化操作诉濒,如家在布局周伦、綁定事件等
  • onStart().這個方法在Activity由不可見變?yōu)榭梢姷臅r候調(diào)用
  • onResume().這個方法在Activity準備好和用戶進行交互的時候調(diào)用。此時的Activity已定位于返回棧的棧頂循诉,并且處于運行狀態(tài)
  • onPause().這個方法在系統(tǒng)準備去啟動或者恢復另一個活動的時候調(diào)用横辆。通常會在這個方法中將一些消耗CPU的資源釋放掉,以及保存一些關鍵數(shù)據(jù),但這個方法的執(zhí)行速度一定要快狈蚤,不然會影響到新的棧頂Activity的活動困肩。
  • onStop().這個方法在Activity完全不可見的時候調(diào)用。它和onPause()方法的主要區(qū)別在于脆侮,如果啟動的新Activity是一個對話框式的Activity锌畸,那么onPause()方法會得到執(zhí)行,而onStop()方法并不會執(zhí)行靖避。
  • onDestroy().這個方法在Activity被銷毀之前調(diào)用潭枣,之后Activity的狀態(tài)編程銷毀狀態(tài)
  • onRestart().這個方法在Activity由停止狀態(tài)變?yōu)檫\行狀態(tài)之前調(diào)用,也就是Activity被重新啟動了

以上除了onRestart()方法幻捏,其他的都是兩兩相對的盆犁,從而又可以將Activity分為3種生存期

  • 完整生存期。Activity在onCreate()方法和onDestroy()方法之間所經(jīng)歷的篡九,就是完整生存期谐岁。一般情況下,一個Activity會在onCreate()方法中完成各種初始化操作榛臼,而在onDestroy()方法中完成釋放內(nèi)存的操作伊佃。
  • 可見生存期。Activity在onStart()方法和onStop()方法之間所經(jīng)歷的沛善,就是可見生存期航揉。在可見生存期內(nèi),Activity對于用戶總是可見的金刁,即便有可能無法和用戶進行交互帅涂。可以通過這兩個方法胀葱,合理的管理那些對用戶可見的額資源漠秋。比如在onStart()方法中對資源的加載,而在onStop()方法中對資源進行釋放抵屿,從而保證處于停止狀態(tài)的Activity不會占用過多內(nèi)存
  • 前臺生存期。Activity在onResume()方法和onPause()方法之間所經(jīng)歷的就是前臺生存期捅位。在前臺生存期內(nèi)轧葛,Activity總是處于運行狀態(tài)的,此時的Activity是可以和用戶進行交互的艇搀,平時看到和接觸最多的也就是這個狀態(tài)的Activity
Activity生命周期.png

體驗Activity的生命周期

Activity的生命周期執(zhí)行順序.png

Activity被收回怎么辦

當一個Activity進入了停止狀態(tài)尿扯,是有可能被系統(tǒng)回收的,下面來看一種場景:

應用中有一個Activity A焰雕,用戶在Activity A的基礎上啟動了Activity B衷笋,Activity A就進入了停止狀態(tài),這個時候由于系統(tǒng)內(nèi)存不足矩屁,把Activity A回收掉了辟宗,然后用戶按下Back返回Activity A爵赵,會出現(xiàn)什么情況呢?其實還是會正常顯示Activity A的泊脐,只不過這時并沒有執(zhí)行onRestart()方法空幻,而是會執(zhí)行Activity A的onCreate()方法,因為Activity A在這種情況下會被重新創(chuàng)建一次容客。

這樣看上去好像也沒什么不妥秕铛,但是如果Activity A中存在臨時數(shù)據(jù)或者狀態(tài)的話,比如Activity A中有一個文本輸入框缩挑,已經(jīng)輸入了一段文字但两,然后啟動Activity B之后,Activity A被系統(tǒng)回收供置,當你點擊Back鍵返回后由于重新走了onCreate()方法镜遣,因此剛才輸入的內(nèi)容就沒有了,那這種情況就會影響用戶體驗士袄,因此要想辦法解決這個問題悲关。

其實在Activity中還提供了一個onSaveInstanceState()回調(diào)方法,這個方法可以保證在活動被回收之前一定會被調(diào)用娄柳,因此可以通過這個方法解決Activity被回收時臨時數(shù)據(jù)或狀態(tài)得不到保存的問題寓辱。

onSaveInstanceState()會攜帶一個Bundle類型的參數(shù),Bundle提供了一系列的方法用于保存數(shù)據(jù)赤拒,比如使用putString()方法保存字符串秫筏,使用putInt()保存整型數(shù)據(jù),以此類推挎挖。每個方法需要兩個參數(shù)这敬,第一個參數(shù)是鍵,用于后面從Bundle中取值蕉朵,另外一個參數(shù)是真正要保存的內(nèi)容崔涂。

在MainActivity中添加如下代碼將臨時數(shù)據(jù)進行保存:

// 保存臨時數(shù)據(jù)
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        String tempData = "Something you just typed";
        outState.putString("data_key", tempData);
    }

在onCreate()方法中也有一個Bundle類型的參數(shù),該參數(shù)一般情況下都是null始衅,但是如果在Activity被系統(tǒng)回收前有通過onSaveInstanceState()方法來保存數(shù)據(jù)的話冷蚂,這個參數(shù)就會帶有之前所保存的所有數(shù)據(jù),只需要通過相應的取值方法將數(shù)據(jù)取出即可汛闸。

修改MainActivity中的onCreate()方法蝙茶,如下:

@Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Log.d(TAG, "onCreate:");
      if (savedInstanceState != null) {
          String tempData = savedInstanceState.getString("data_key");
          Log.d(TAG, tempData);
      }
  }

取出值之后再做相應的恢復操作就可以了,比如說將文本內(nèi)容重新賦值到文本框中等等诸老。

使用Bundle來保存數(shù)據(jù)跟使用Intent傳遞數(shù)據(jù)類似隆夯。Intent還可以結(jié)合Bundle一起用于傳遞數(shù)據(jù),首先可以把需要傳遞的數(shù)據(jù)都保存在Bundle對象中,然后再將Bundle對象存在Intent中蹄衷,到了目標Activity之后先從Intent中取出Bundle忧额,再從Bundle中一一去處數(shù)據(jù)。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宦芦,一起剝皮案震驚了整個濱河市宙址,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌调卑,老刑警劉巖抡砂,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異恬涧,居然都是意外死亡注益,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門溯捆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丑搔,“玉大人,你說我怎么就攤上這事提揍∑≡拢” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵劳跃,是天一觀的道長谎仲。 經(jīng)常有香客問我,道長刨仑,這世上最難降的妖魔是什么郑诺? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮杉武,結(jié)果婚禮上辙诞,老公的妹妹穿的比我還像新娘。我一直安慰自己轻抱,他們只是感情好飞涂,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著十拣,像睡著了一般封拧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夭问,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天,我揣著相機與錄音曹铃,去河邊找鬼缰趋。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的秘血。 我是一名探鬼主播味抖,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灰粮!你這毒婦竟也來了仔涩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤粘舟,失蹤者是張志新(化名)和其女友劉穎熔脂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柑肴,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡霞揉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了晰骑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片适秩。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖硕舆,靈堂內(nèi)的尸體忽然破棺而出秽荞,到底是詐尸還是另有隱情,我是刑警寧澤抚官,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布扬跋,位于F島的核電站,受9級特大地震影響耗式,放射性物質(zhì)發(fā)生泄漏胁住。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一刊咳、第九天 我趴在偏房一處隱蔽的房頂上張望彪见。 院中可真熱鬧,春花似錦娱挨、人聲如沸余指。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酵镜。三九已至,卻和暖如春柴钻,著一層夾襖步出監(jiān)牢的瞬間淮韭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工贴届, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留靠粪,地道東北人蜡吧。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像占键,于是被迫代替她去往敵國和親昔善。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容