通過(guò)返回棧的活動(dòng)來(lái)理解Activity生命周期

Android中最常用的無(wú)非就是Activity,
而精通其中的原理和生命周期也是一個(gè)Android程序員必備的技能,包括在面試的時(shí)候很多問(wèn)題都會(huì)涉及到activity生命周期。

當(dāng)我們啟動(dòng)一個(gè)app的時(shí)候,其實(shí)就已經(jīng)開(kāi)始了activity的生命,
而這一開(kāi)始的activity就是MainActivity,基本在我們創(chuàng)建應(yīng)用的時(shí)候就存在了。

下面一張圖來(lái)幫助我們了解生命周期。

圖片來(lái)源網(wǎng)絡(luò)

Activity中一共有七大生命周期,來(lái)控制整個(gè)應(yīng)用的活動(dòng),

從onCreate()開(kāi)始
到onDestory()結(jié)束
已經(jīng)用掉了兩條命

真正需要我們折騰的是剩下的5條命。

關(guān)于返回棧(Task),在《第一行代碼Android第二版》書(shū)中解釋是

其實(shí)Android是使用任務(wù)(Task)來(lái)管理活動(dòng)的,一個(gè)任務(wù)就是一組存放在棧里活動(dòng)的集合,這個(gè)棧也被稱(chēng)為返回棧(Back Stack)。

通俗的理解就是說(shuō),每一次啟動(dòng)一個(gè)新的Activity,然后這個(gè)啟動(dòng)的活動(dòng)就被存放在返回棧中,并且處于棧頂的位置。這個(gè)過(guò)程稱(chēng)為入棧。

反之當(dāng)一個(gè)活動(dòng)結(jié)束-Activity被銷(xiāo)毀(finsh())的時(shí)候,或者按下了返回鍵(back)那么這個(gè)活動(dòng)的activity就會(huì)被當(dāng)做垃圾清理出去。這個(gè)過(guò)程稱(chēng)為出棧

因?yàn)榉祷貤J且粋€(gè)集合,用數(shù)組的形式存放Activity活動(dòng)的,所以在啟動(dòng)Activity的時(shí)候,數(shù)組中就會(huì)在棧頂增加一個(gè)活動(dòng),而之前處于棧頂?shù)幕顒?dòng)自動(dòng)給新來(lái)的讓位。所以我們總是能看到最新的界面。

圖片來(lái)源網(wǎng)絡(luò)

Activity生命周期

當(dāng)我們打開(kāi)一個(gè)Activity的時(shí)候會(huì)執(zhí)行生命周期中的onCreate()、onState()、onResume()這三個(gè)方法,

onCreate()用于加載布局,加載數(shù)據(jù),實(shí)例化控件、監(jiān)聽(tīng),等。返回棧收到請(qǐng)求加入指令。
onState()將開(kāi)啟活動(dòng),由于布局,數(shù)據(jù)是不可見(jiàn),靜態(tài)的,當(dāng)啟動(dòng)該方法時(shí),將其變?yōu)榭梢?jiàn),活動(dòng)的。也可以理解為活動(dòng)通過(guò)指令,開(kāi)始存放到返回棧中。
onResume()加載完成靜態(tài)時(shí)執(zhí)行的活動(dòng),這時(shí)候活動(dòng)已處于棧頂。并且用戶(hù)可見(jiàn),可操作控件,就像一個(gè)出列等待命令的將士。

接著要進(jìn)行下一步,打開(kāi)另一個(gè)Activity,那么之前的Activity還需要繼續(xù)走完他的生命周期,于是又開(kāi)始執(zhí)行:

onPause()到這里收到準(zhǔn)備撤的命令,但是還沒(méi)行動(dòng),此時(shí)活動(dòng)依然處于棧頂?shù)奈恢?。?yè)面處于可見(jiàn)狀態(tài)。

但是這時(shí)候突然士兵想去wc怎么辦,或者行李沒(méi)帶?吃一碗他媳婦給他送行的面?。這時(shí)候就要返回一下,比如彈個(gè)窗口,上面掛著吃飯的牌子,吃完后再進(jìn)入待命狀態(tài),那么這期間的一個(gè)小動(dòng)作就執(zhí)行了

onResume()利用交互改變狀態(tài)。
onPause()

這時(shí)候的士兵可能就是一個(gè)吃飽飯,或者餓著肚子的,都有可能,然后依然是等候命令,可能沒(méi)有飯吃了,于是:

onStop()撤退,頁(yè)面已經(jīng)被新的Activity覆蓋,新的Activity占據(jù)了棧頂。原Activity不可見(jiàn)?;顒?dòng)停止

你以為這就結(jié)束了?當(dāng)然沒(méi)有,君子報(bào)仇十年不晚,無(wú)論新的Activity如何折騰,只要他按下的返回鍵(back),或者調(diào)用了finish(),就會(huì)又執(zhí)行:

onRestart()重啟活動(dòng)
onStart()
onResume()

但是如果新的Activity剛獲得棧頂?shù)奈恢?,又被第三個(gè)Activity加入,那么剛開(kāi)始的Activity就失去了返回(finish()/back)的機(jī)會(huì),所以只能結(jié)束自己的生命:

onDestory()終止活動(dòng)。

我們?cè)陂_(kāi)發(fā)時(shí),用的最多的就是onCreate,初始化數(shù)據(jù)。
然后是onResume,刷新數(shù)據(jù)。
有些網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)就是在onResume方法執(zhí)行,因?yàn)橛锌赡茉谖覀儧](méi)有銷(xiāo)毀前一個(gè)Activity的時(shí)候,之前的Activity數(shù)據(jù)集發(fā)生變化,返回直接執(zhí)行onState,因?yàn)樵摲椒ㄖ皇怯脕?lái)轉(zhuǎn)換靜態(tài)數(shù)據(jù)的,而onResume是用來(lái)處理交互的。
所以需要在這里刷新數(shù)據(jù)。

在我們手機(jī)上開(kāi)發(fā)者模式中有個(gè)保留活動(dòng)的選項(xiàng),默認(rèn)是選中的,如果不保留的話那么在按手機(jī)Home鍵的話,活動(dòng)就會(huì)被銷(xiāo)毀也就是執(zhí)行onDestory,否則是一直停在onStop狀態(tài)。

有時(shí)候我們會(huì)發(fā)現(xiàn)Home之后再打開(kāi)的話app重啟了,這是因?yàn)閮?nèi)存不足,有些手機(jī)系統(tǒng)自動(dòng)幫我們終結(jié)掉了無(wú)用的活動(dòng)。

onSaveInstanceState
最后提一下這個(gè)方法,可能在我們開(kāi)發(fā)時(shí)用的少,在stop方法里左邊有個(gè)直接返回到onCreate方法里的活動(dòng)。
指的是進(jìn)程被殺死的情況,有可能是處于后臺(tái)運(yùn)行時(shí)被殺死,再進(jìn)來(lái)就會(huì)重新執(zhí)行onCreate,過(guò)程中會(huì)產(chǎn)生該方法。

從字面很容易理解,就是保存實(shí)例。因?yàn)楫?dāng)活動(dòng)被殺死后,頁(yè)面修改過(guò)的內(nèi)容就會(huì)丟失,比如一些設(shè)置還沒(méi)保存,修改信息未提交這種。
那么利用onSaveInstanceState就可以保存臨時(shí)數(shù)據(jù)。

使用方法:

   @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key","value");
    }
......

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.httptest);
        savedInstanceState.getString("key");

    }

BUG

1、
如果我們?cè)趏nResume進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求的話,可能出現(xiàn)一個(gè)沖突,在進(jìn)去Activity的時(shí)候,我們?cè)O(shè)置的默認(rèn)布局會(huì)優(yōu)先加載,如果網(wǎng)絡(luò)差的話,網(wǎng)絡(luò)數(shù)據(jù)一直加載不出來(lái),所顯示的就是默認(rèn)我們后臺(tái)寫(xiě)死的布局。

如果涉及到相關(guān)操作需要網(wǎng)絡(luò)加載完成操作的可以提前把按鈕設(shè)置為隱藏、或者設(shè)置gone,還可以設(shè)置加載中效果,推薦設(shè)置加載等待效果。

2、
Fragment生命周期是依賴(lài)于Activity生命周期的,比如MainActivity下有四個(gè)Fragment,當(dāng)Fragment里面的Activity活動(dòng)發(fā)生變化可以直接影響到整個(gè)MainActivity,當(dāng)然也包括四個(gè)Fragment。

所以當(dāng)我們?cè)诓僮鱂ragment里面的Activity活動(dòng)的時(shí)候,要注意在返回的時(shí)候通知Fragment里的數(shù)據(jù)更新,或者是把數(shù)據(jù)請(qǐng)求的方法直接在Fragment的onResume方法里實(shí)現(xiàn)。


END
由于本來(lái)對(duì)生命周期的了解都不夠全面,加之最近項(xiàng)目中遇到的一些小毛病,也是跟生命周期相關(guān),所以就參考了一些資料,以個(gè)人的思路做了理解。
有不足的地方還望多指出!

參考資料:
《第一行代碼》
Android任務(wù)和返回棧完全解析,細(xì)數(shù)那些你所不知道的細(xì)節(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,078評(píng)論 25 709
  • 引言:這篇文章,大概分析下Fragment的生命周期、實(shí)際應(yīng)用方法以及使用Fragment時(shí)需要注意的地方,算是F...
    androidjp閱讀 13,105評(píng)論 10 104
  • 【又是那個(gè)夢(mèng)】 “打死你個(gè)小東西,看我怎么收拾你?!币粋€(gè)四十多歲的男人揮舞著手中的木棍向我砸來(lái)。他發(fā)紅的眼眶在黑夜...
    花下人閱讀 308評(píng)論 0 1
  • 今天一天上午連著要上三節(jié)課,我本以為作業(yè)會(huì)來(lái)不及改完給同學(xué)們,要犧牲中午的時(shí)間來(lái)改作業(yè),但結(jié)果出乎我的意料,我在上...
    95d299188023閱讀 318評(píng)論 0 0
  • 戀愛(ài)是兩個(gè)人的事,婚姻則是兩個(gè)家庭的事。有多少婚姻的不幸,不是來(lái)源于小三,而是婆媳問(wèn)題。 剛結(jié)婚的時(shí)候總是單純的以...
    晚風(fēng)心聲閱讀 863評(píng)論 10 2

友情鏈接更多精彩內(nèi)容