Android Activity生命周期及啟動模式

學(xué)習(xí)Android開發(fā)的小伙伴可能“四大組件”是接觸Android開發(fā)時經(jīng)常出現(xiàn)的名詞之一,四大組件的使用也是入門Android開發(fā)必備的基礎(chǔ)技能之一,這篇文章采用代碼示例的方法嘗試分析四大組件的基本使用以及各個組件的基本原理乐严。

那么,Android的四大組件究竟是哪四大組件呢?四大組件包括:Activity,Service摧扇,BroadCastReceiver,ContentProvider挚歧。本篇文章將分析Activity的生命周期及其啟動模式

生命周期:

Activity有以下幾個生命周期方法扛稽,他們分別代表什么含義,我們在每個生命周期方法中究竟應(yīng)該完成什么樣的準(zhǔn)備工作:

onCreate:表示Activity正在被創(chuàng)建滑负,這是Activity生命周期的第一個方法在张,我們可以在這個方法中做一些初始化的工作,比如setContentView去加載布局文件矮慕,綁定控件帮匾,初始化Activity所需數(shù)據(jù)等。

onStart:表示Activity正在被啟動痴鳄,這個時候Activity已經(jīng)可見瘟斜,但是還沒有顯示到前臺,無法與用戶進行交互,可以理解為界面已經(jīng)顯示了哼转,但是我們還看不到明未。

onResume:表示Activity已經(jīng)可見槽华,已經(jīng)顯示到前臺了壹蔓,并可以與用戶進行交互。

onPause:表示Activity正在停止猫态,在這個生命周期中佣蓉,我們可以做一些保存數(shù)據(jù)、停止動畫等工作亲雪,不能做比較耗時的工作勇凭。

onStop:表示Activity即將停止,我們可以做一些資源回收工作义辕,同樣不能太耗時

onDestroy:表示Activity即將背銷毀虾标,這里是Activity生命周期的最后一個方法,我們可以做一些資源釋放工作灌砖。

onRestart:表示Activity正在被重新啟動璧函,當(dāng)前Activity從不可見狀態(tài)變?yōu)榭梢姞顟B(tài),這個方法在什么時候會被調(diào)用呢基显?當(dāng)你在一個Activity中按下Home鍵切換到桌面或是打開一個新的Activity(打開新的Activity是否調(diào)用onRestart方法與Activity的啟動模式有關(guān)蘸吓,暫可不表,文章后面會有介紹)時撩幽,系統(tǒng)會調(diào)用Activity的onPause库继、onStop生命周期方法,當(dāng)你回到這個Activity時窜醉,如果這個Activity沒有被系統(tǒng)回收宪萄,就會調(diào)用onRestart方法

Activity的生命周期如下圖所示:

image

下面我會用代碼說明Activity各種情境下的生命周期:

以下是MainActivity的代碼


package com.danc.dancactivitystudy;

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Button;

public class MainActivityextends AppCompatActivity {

    private static final StringTAG ="danKeeper";

    private ButtonmBtnJump;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Log.d(TAG, "MainActivity onCreate() be called");

        setContentView(R.layout.activity_main);

        mBtnJump = findViewById(R.id.btn_jump);

        mBtnJump.setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View view) {

              startActivity(new Intent(MainActivity.this, SecondActivity.class));

         }

});

    }

@Override

    protected void onStart() {

        Log.d(TAG, "MainActivity onStart() be called");

        super.onStart();

    }

@Override

    protected void onResume() {

        Log.d(TAG, "MainActivity onResume() be called");

        super.onResume();

    }

@Override

    protected void onPause() {

        Log.d(TAG, "MainActivity onPause() be called");

        super.onPause();

    }

@Override

    protected void onStop() {

        Log.d(TAG, "MainActivity onStop() be called");

        super.onStop();

    }

@Override

    protected void onDestroy() {

        Log.d(TAG, "MainActivity onDestroy() be called");

        super.onDestroy();

    }

@Override

    protected void onRestart() {

        Log.d(TAG, "MainActivity onRestart() be called");

        super.onRestart();

    }

}

以下是SecondActivity的代碼


package com.danc.dancactivitystudy;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

public class SecondActivityextends AppCompatActivity {

private static final StringTAG ="danKeeper";

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        Log.d(TAG, "SecondActivity onCreate() be called");

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

    }

@Override

    protected void onStart() {

        Log.d(TAG, "SecondActivity onStart() be called");

        super.onStart();

    }

@Override

    protected void onResume() {

        Log.d(TAG, "SecondActivity onResume() be called");

        super.onResume();

    }

@Override

    protected void onPause() {

        Log.d(TAG, "SecondActivity onPause() be called");

        super.onPause();

    }

@Override

    protected void onStop() {

        Log.d(TAG, "SecondActivity onStop() be called");

        super.onStop();

    }

@Override

    protected void onDestroy() {

        Log.d(TAG, "SecondActivity onDestroy() be called");

        super.onDestroy();

    }

@Override

    protected void onRestart() {

        Log.d(TAG, "SecondActivity onRestart() be called");

        super.onRestart();

    }

}

(一)啟動MainActivity

日志如下


MainActivity onCreate() be called

MainActivity onStart() be called

MainActivity onResume() be called

說明這個情況下MainActivity的生命周期是:

onCreate > onStart > onResume

(二)跳轉(zhuǎn)至SecondActivity

日志如下


MainActivity onCreate() be called

MainActivity onStart() be called

MainActivity onResume() be called

MainActivity onPause() be called

SecondActivity onCreate() be called

SecondActivity onStart() be called

SecondActivity onResume() be called

MainActivity onStop() be called

說明這個情況下的生命周期是:

onCreate > onStart > onResume > onPause > SecondActivity onCreate > SecondActivity onStart > SecondActivity onResume > onStop

也就是說頁面跳轉(zhuǎn)時是先執(zhí)行MainActivity的onPause生命周期,然后開始執(zhí)行SecondActivity的生命周期榨惰,當(dāng)SecondActivity頁面可見之后拜英,MainActivity執(zhí)行onStop生命周期

(三)返回鍵返回第一個Activity

日志如下


SecondActivity onPause() be called

MainActivity onRestart() be called

MainActivity onStart() be called

MainActivity onResume() be called

SecondActivity onStop() be called

SecondActivity onDestroy() be called

說明這個情況下的生命周期是:

SecondActivity onPause > onRestart > onStart > onResume > SecondActivity onStop > SecondActivity onDestroy

這里我們可以看到走到了onRestart生命周期,這是由于跳轉(zhuǎn)到SecondActivity時MainActivity并沒有被銷毀读串,也就是沒有走到onDestroy生命周期聊记,所以當(dāng)返回上一頁面也就是返回MainActivity時會走到MainActivity的onRestart生命周期。這里會有一個特殊情況恢暖,如果SecondActivity采用了透明主題排监,跳轉(zhuǎn)至SecondActivity時并不會走到onStop生命周期,同樣的杰捂,返回時也不會走到onStart生命周期舆床,生命周期變?yōu)椋?br> onCreate > onStart > onResume > onPause > SecondActivity onCreate > SecondActivity onStart > SecondActivity onResume > SecondActivity onPause > onResume > SecondActivity onStop > SecondActivity onDestroy

啟動模式:

我們知道,默認(rèn)情況下,啟動同一個Activity時系統(tǒng)會創(chuàng)建多個實例并把它們放到任務(wù)棧中挨队,當(dāng)我們按下返回鍵時谷暮,會一一展示我們剛剛打開的Activity,每按一次返回鍵棧頂?shù)腁ctivity就會出棧盛垦,直到検遥空為止。那么問題來了腾夯,為什么創(chuàng)建一個Activity時就要將一個新的實例入棧呢颊埃?為什么不從棧中看看是否有這個Activity的實例呢?Android設(shè)計的時候就提供了四種Activity的啟動模式來供開發(fā)者選擇蝶俱,每種啟動模式都有他們的特性以及使用場景班利。

standard:

標(biāo)準(zhǔn)模式,這也是系統(tǒng)的默認(rèn)啟動模式榨呆。每次新啟動一個Activity時都會實例化該Activity對象罗标,不管任務(wù)棧中是否已經(jīng)有這個Activity的實例。

singleTop:

棧頂復(fù)用模式积蜻。新啟動一個Activity時會檢查任務(wù)棧頂是否是該Activity的實例闯割,如果是,就不會重新創(chuàng)建這個Activity浅侨,同時onIntent方法會被回調(diào)纽谒,如果不是,就會添加一個新的該Activity實例到棧頂如输。舉個例子鼓黔,假如現(xiàn)在任務(wù)棧從棧頂?shù)綏5追謩e為ABCD四個Activity,如果這時跳轉(zhuǎn)至A不见,如果A的啟動模式為singleTop澳化,那么任務(wù)棧的結(jié)構(gòu)就是ABCD,如果是stantard稳吮,那么任務(wù)棧的結(jié)構(gòu)就是AABCD缎谷。

singleTask;

棧內(nèi)復(fù)用模式。這是一種單實例模式灶似,只要Actiivty在一個任務(wù)棧存在列林,那么啟動這個Activity都不會創(chuàng)建新的實例,而是將任務(wù)棧中Activity調(diào)到棧頂酪惭,調(diào)用它的onNewIntent方法希痴,如果任務(wù)棧中不存在這個Activity的實例,則會創(chuàng)建Activity的實例并入棧春感。比如任務(wù)棧S1中有ABC三個Activity砌创,此時我要進入D虏缸,如果D需要的任務(wù)棧是S2,那么系統(tǒng)會先創(chuàng)建S2任務(wù)棧嫩实,并將D入棧刽辙,棧結(jié)構(gòu)為S1:ABC,S2:D甲献,如果D需要的任務(wù)棧就是S1宰缤,那么系統(tǒng)會創(chuàng)建一個D的實例并入棧,那么此時S1中就是DABC竟纳,此時我們在跳轉(zhuǎn)到B中撵溃,那么S1任務(wù)棧中就會變?yōu)锽C。

singleInstance:

singleInstance除了具有singleTask所有特性之外锥累,singleInstance啟動模式下的Activity只 能單獨位于一個任務(wù)棧中,換句話說集歇,當(dāng)要啟動A時桶略,只要所有任務(wù)棧中沒有A的實例,系統(tǒng)就會為A創(chuàng)建一個任務(wù)棧诲宇,這個任務(wù)棧中只會存在A际歼,后續(xù)要進入A,都不會創(chuàng)建新的實例姑蓝,直到系統(tǒng)將這個特殊的任務(wù)椂煨模回收。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纺荧,一起剝皮案震驚了整個濱河市旭愧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宙暇,老刑警劉巖输枯,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異占贫,居然都是意外死亡桃熄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門型奥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瞳收,“玉大人,你說我怎么就攤上這事厢汹∶睿” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵坑匠,是天一觀的道長血崭。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么夹纫? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任咽瓷,我火速辦了婚禮,結(jié)果婚禮上舰讹,老公的妹妹穿的比我還像新娘茅姜。我一直安慰自己,他們只是感情好月匣,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布钻洒。 她就那樣靜靜地躺著号杏,像睡著了一般刁标。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娇跟,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天萍悴,我揣著相機與錄音头遭,去河邊找鬼。 笑死癣诱,一個胖子當(dāng)著我的面吹牛计维,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撕予,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鲫惶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了实抡?” 一聲冷哼從身側(cè)響起欠母,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澜术,沒想到半個月后艺蝴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鸟废,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年猜敢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盒延。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缩擂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出添寺,到底是詐尸還是另有隱情胯盯,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布计露,位于F島的核電站博脑,受9級特大地震影響憎乙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叉趣,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一泞边、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疗杉,春花似錦阵谚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至朝聋,卻和暖如春嗡午,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玖翅。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工翼馆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人金度。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像严沥,于是被迫代替她去往敵國和親猜极。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

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