第三章:Activity簡(jiǎn)介和Fragment應(yīng)用

Activity的生命周期

Activity是由Activity棧進(jìn)管理,當(dāng)來到一個(gè)新的Activity后错妖,此Activity將被加入到Activity棧頂规辱,之前的Activity位于此Activity底部谆棺。Acitivity一般意義上有四種狀態(tài):

1.當(dāng)Activity位于棧頂時(shí),此時(shí)正好處于屏幕最前方按摘,此時(shí)處于運(yùn)行狀態(tài)包券;

2.當(dāng)Activity失去了焦點(diǎn)但仍然對(duì)用于可見(如棧頂?shù)腁ctivity是透明的或者棧頂Activity并不是鋪滿整個(gè)手機(jī)屏幕),此時(shí)處于暫停狀態(tài)炫贤;

3.當(dāng)Activity被其他Activity完全遮擋溅固,此時(shí)此Activity對(duì)用戶不可見,此時(shí)處于停止?fàn)顟B(tài)兰珍;

4.當(dāng)Activity由于人為或系統(tǒng)原因(如低內(nèi)存等)被銷毀侍郭,此時(shí)處于銷毀狀態(tài);

在每個(gè)不同的狀態(tài)階段掠河,Android系統(tǒng)對(duì)Activity內(nèi)相應(yīng)的方法進(jìn)行了回調(diào)亮元。因此,我們?cè)诔绦蛑袑慉ctivity時(shí)唠摹,一般都是繼承Activity類并重寫相應(yīng)的回調(diào)方法爆捞。

圖中詳細(xì)給出了Activity整個(gè)生命周期的過程,以及在不同的狀態(tài)期間相應(yīng)的回調(diào)方法勾拉。

圖中需要注意一下幾點(diǎn):

1.Activity實(shí)例是由系統(tǒng)自動(dòng)創(chuàng)建煮甥,并在不同的狀態(tài)期間回調(diào)相應(yīng)的方法。一個(gè)最簡(jiǎn)單的完整的Activity生命周期會(huì)按照如下順序回調(diào):onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy藕赞。稱之為entire lifetime成肘。

2.當(dāng)執(zhí)行onStart回調(diào)方法時(shí),Activity開始被用戶所見(也就是說斧蜕,onCreate時(shí)用戶是看不到此Activity的双霍,那用戶看到的是哪個(gè)?當(dāng)然是此Activity之前的那個(gè)Activity)批销,一直到onStop之前洒闸,此階段Activity都是被用戶可見,稱之為visible lifetime风钻。

3.當(dāng)執(zhí)行到onResume回調(diào)方法時(shí)顷蟀,Activity可以響應(yīng)用戶交互,一直到onPause方法之前骡技,此階段Activity稱之為foreground lifetime鸣个。

在實(shí)際應(yīng)用場(chǎng)景中羞反,假設(shè)A Activity位于棧頂,此時(shí)用戶操作囤萤,從A Activity跳轉(zhuǎn)到B Activity昼窗。那么對(duì)AB來說,具體會(huì)回調(diào)哪些生命周期中的方法呢涛舍?回調(diào)方法的具體回調(diào)順序又是怎么樣的呢澄惊?

開始時(shí),A被實(shí)例化富雅,執(zhí)行的回調(diào)有A:onCreate -> A:onStart -> A:onResume掸驱。

當(dāng)用戶點(diǎn)擊A中按鈕來到B時(shí),假設(shè)B全部遮擋住了A没佑,將依次執(zhí)行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop毕贼。

此時(shí)如果點(diǎn)擊Back鍵,將依次執(zhí)行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy蛤奢。

至此鬼癣,Activity棧中只有A。在Android中啤贩,有兩個(gè)按鍵在影響Activity生命周期這塊需要格外區(qū)分下待秃,即Back鍵和Home鍵。我們先直接看下實(shí)驗(yàn)結(jié)果:

此時(shí)如果按下Back鍵痹屹,系統(tǒng)返回到桌面章郁,并依次執(zhí)行A:onPause -> A:onStop -> A:onDestroy。

此時(shí)如果按下Home鍵(非長(zhǎng)按)志衍,系統(tǒng)返回到桌面驱犹,并依次執(zhí)行A:onPause -> A:onStop。由此可見足画,Back鍵和Home鍵主要區(qū)別在于是否會(huì)執(zhí)行onDestroy。

此時(shí)如果長(zhǎng)按Home鍵佃牛,不同手機(jī)可能彈出不同內(nèi)容淹辞,Activity生命周期未發(fā)生變化(由小米2s測(cè)的,不知道其他手機(jī)是否會(huì)對(duì)Activity生命周期有影響)俘侠。

由于Android本身的特性象缀,使得現(xiàn)在不少應(yīng)用都沒有直接退出應(yīng)用程序的功能,按照一般的邏輯爷速,當(dāng)Activity棧中有且只有一個(gè)Activity時(shí)央星,當(dāng)按下Back鍵此Activity會(huì)執(zhí)行onDestroy,那么下次點(diǎn)擊此應(yīng)用程圖標(biāo)將從重新啟動(dòng)惫东,因此莉给,當(dāng)前不少應(yīng)用程序都是采取如Home鍵的效果毙石,當(dāng)點(diǎn)擊了Back鍵,系統(tǒng)返回到桌面颓遏,然后點(diǎn)擊應(yīng)用程序圖標(biāo)徐矩,直接回到之前的Activity界面,這種效果是怎么實(shí)現(xiàn)的呢叁幢?

通過重寫按下Back鍵的回調(diào)函數(shù)滤灯,轉(zhuǎn)成Home鍵的效果即可。

@Override

public void onBackPressed() {

? ? Intent home = new Intent(Intent.ACTION_MAIN);

? ? home.addCategory(Intent.CATEGORY_HOME);

? ? startActivity(home);

}

當(dāng)然曼玩,此種方式通過Home鍵效果強(qiáng)行影響到Back鍵對(duì)Activity生命周期的影響鳞骤。注意,此方法只是針對(duì)按Back鍵需要退回到桌面時(shí)的Activity且達(dá)到Home效果才重寫黍判。

或者豫尽,為達(dá)到此類效果,Activity實(shí)際上提供了直接的方法样悟。

activity.moveTaskToBack(true);? //moveTaskToBack()此方法直接將當(dāng)前Activity所在的Task移到后臺(tái)拂募,同時(shí)保留activity順序和狀態(tài)。

在之前的項(xiàng)目開發(fā)過程中窟她,當(dāng)時(shí)遇到一個(gè)很奇怪的問題:手機(jī)上的“開發(fā)者選項(xiàng)”中有一個(gè)“不保留活動(dòng)”的設(shè)置陈症,當(dāng)開啟此設(shè)置,手機(jī)上的設(shè)置提示是“用戶離開后即銷毀每個(gè)活動(dòng)”震糖,開啟后录肯,對(duì)于其他的應(yīng)用程序是從A Acticity到B Activity,然后Back鍵回到A吊说,此時(shí)论咏,其他應(yīng)用程序只是先白屏(有可能黑屏等,取決于主題設(shè)置)一下颁井,然后A開始可見厅贪,但是我的應(yīng)用程序中出現(xiàn)的一個(gè)結(jié)果卻是直接返回到了桌面。一開始百思不得其解雅宾。最后終于定位出問題养涮。首先,我們需要明確開啟此設(shè)置項(xiàng)后對(duì)Activity生命周期的影響眉抬。開啟此設(shè)置項(xiàng)后贯吓,當(dāng)A到B時(shí),假設(shè)B全部遮擋住了A蜀变,將依次執(zhí)行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop -> A:onDestroy悄谐。是的,A在系統(tǒng)原本的生命周期回調(diào)中增加了onDestroy库北。此即“用戶離開后即銷毀每個(gè)活動(dòng)”的含義爬舰。但此時(shí)需要注意的是们陆,只要沒有認(rèn)為的調(diào)用A的finish()方法,雖然A執(zhí)行了onDestroy洼专,但Activity棧中依然保留有A棒掠,此時(shí)B處于棧頂。那么在B中按Back鍵回到A時(shí)屁商,將依次執(zhí)行:B:onPause -> A:onCreate -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy烟很。沒錯(cuò),A從onCreate開始執(zhí)行了蜡镶。此處也就解釋了為什么A可能會(huì)出現(xiàn)白屏(或黑屏等)一下的原因了雾袱。

那么為什么我的應(yīng)用程序會(huì)跟其他應(yīng)用程序出現(xiàn)不一樣呢?最后定為出問題在于當(dāng)時(shí)我的應(yīng)用程序中為了做到完全退出應(yīng)用程序效果,專門使用了一個(gè)Activity棧去維護(hù)Activity(當(dāng)時(shí)是借鑒了網(wǎng)上的此類實(shí)現(xiàn)方案官还,現(xiàn)在想想芹橡,實(shí)在沒必要,且不說Android本身特性決定了沒必要通過如此方法去達(dá)到退出效果望伦,僅僅是此方法本身也存在很大的問題林说,現(xiàn)在在網(wǎng)上依然能見到有不少文章說到應(yīng)用程序退出可以使用此方法,哎屯伞。腿箩。),在onCreate中入棧劣摇,onDestroy出棧珠移,調(diào)用了如下方法

AppManager.getAppManager().finishActivity(this);

其中,AppManager中finishActivity函數(shù)具體定義是:

/**

* 結(jié)束指定的Activity

*/

public void finishActivity(Activity activity) {

? ? if (activity != null) {

? ? ? ? activityStack.remove(activity);

? ? ? ? activity.finish();

? ? ? ? activity = null;

? ? }

}

至此末融,相信大家應(yīng)該看出問題的所在了吧钧惧。

沒錯(cuò),問題在于執(zhí)行了activity的finish()方法9聪啊浓瞪! activity的finish()方法至少有兩個(gè)層面含義,1.將此Activity從Activity棧中移除巧婶,2.調(diào)用了此Activity的onDestroy方法追逮。對(duì)于不開啟“不保留活動(dòng)”的設(shè)置項(xiàng),實(shí)際上也沒什么影響粹舵,但是一旦開啟此設(shè)置,問題顯露無疑骂倘。開啟此此設(shè)置后眼滤,正常情況下離開A,即使執(zhí)行了A的onDestroy历涝,Activity棧中還是有A的诅需,但是我這樣寫后漾唉,finish()方法一執(zhí)行,Activity棧中就沒有A了堰塌,因此赵刑,當(dāng)點(diǎn)擊Back鍵時(shí),Activity棧中已經(jīng)沒有此應(yīng)用的任何Activity了场刑,直接來到了手機(jī)桌面般此。

可能,有些人會(huì)說牵现,我就是要通過此種方法想去完全退出應(yīng)用程序铐懊,同時(shí)希望自己的Activity棧和系統(tǒng)中Activity棧保持一致,怎么辦呢瞎疼?

在此科乎,可以通過如下改寫去實(shí)現(xiàn):

/**

* 結(jié)束指定的Activity

*/

public void finishActivity(Activity activity) {

? ? if (activity != null) {

? ? // 為與系統(tǒng)Activity棧保持一致,且考慮到手機(jī)設(shè)置項(xiàng)里的"不保留活動(dòng)"選項(xiàng)引起的Activity生命周期調(diào)用onDestroy()方法所帶來的問題,此處需要作出如下修正

? ? if(activity.isFinishing()){

? ? ? ? activityStack.remove(activity);

? ? ? ? //activity.finish();

? ? ? ? activity = null;

? ? }

? ? }

}

創(chuàng)建與配置Activity

1.新建java類贼急,并繼承Activity類茅茂;

2.重寫onCreate方法;

3.setContentView(R.layout.activity_main)太抓;

4.AndroidManifest.xml中添加Activity空闲;

注:可以在Android Studio中直接新建Activity免去上述流程;

啟動(dòng)和關(guān)閉Activity

1.在配置文件AndroidManifest.xml中開啟程序默認(rèn)窗口:

<intent-filter>

? ? <action android:name="android.intent.action.MAIN" />

? ? <category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

2.其他Activity需要通過startActivity()命令來調(diào)用啟動(dòng)腻异;

3. 通過新建Intent類達(dá)成頁面跳轉(zhuǎn)功能:

Intent intent=new Intent(MainActivity.this,類名.class);

4.關(guān)閉Activity:finish()方法进副;

注:可通過Bundle類實(shí)現(xiàn)多個(gè)Activity數(shù)據(jù)的交換。

? ? ? ? startActivityForResult()調(diào)用其他Activity并返回結(jié)果悔常。

Fragment簡(jiǎn)介

1.生命周期

Fragment每個(gè)生命周期方法的意義影斑、作用(注意紅色的不是生命周期方法):

setUserVisibleHint():設(shè)置Fragment可見或者不可見時(shí)會(huì)調(diào)用此方法。在該方法里面可以通過調(diào)用getUserVisibleHint()獲得Fragment的狀態(tài)是可見還是不可見的机打,如果可見則進(jìn)行懶加載操作矫户。

onAttach():執(zhí)行該方法時(shí),F(xiàn)ragment與Activity已經(jīng)完成綁定残邀,該方法有一個(gè)Activity類型的參數(shù)皆辽,代表綁定的Activity,這時(shí)候你可以執(zhí)行諸如mActivity = activity的操作芥挣。

onCreate():初始化Fragment驱闷。可通過參數(shù)savedInstanceState獲取之前保存的值空免。

onCreateView():初始化Fragment的布局空另。加載布局和findViewById的操作通常在此函數(shù)內(nèi)完成,但是不建議執(zhí)行耗時(shí)的操作蹋砚,比如讀取數(shù)據(jù)庫數(shù)據(jù)列表扼菠。

onActivityCreated():執(zhí)行該方法時(shí)摄杂,與Fragment綁定的Activity的onCreate方法已經(jīng)執(zhí)行完成并返回,在該方法內(nèi)可以進(jìn)行與Activity交互的UI操作循榆,所以在該方法之前Activity的onCreate方法并未執(zhí)行完成析恢,如果提前進(jìn)行交互操作,會(huì)引發(fā)空指針異常秧饮。

onStart():執(zhí)行該方法時(shí)映挂,F(xiàn)ragment由不可見變?yōu)榭梢姞顟B(tài)。

onResume():執(zhí)行該方法時(shí)浦楣,F(xiàn)ragment處于活動(dòng)狀態(tài)袖肥,用戶可與之交互。

onPause():執(zhí)行該方法時(shí)振劳,F(xiàn)ragment處于暫停狀態(tài)椎组,但依然可見,用戶不能與之交互历恐。

onSaveInstanceState():保存當(dāng)前Fragment的狀態(tài)寸癌。該方法會(huì)自動(dòng)保存Fragment的狀態(tài),比如EditText鍵入的文本弱贼,即使Fragment被回收又重新創(chuàng)建蒸苇,一樣能恢復(fù)EditText之前鍵入的文本。

onStop():執(zhí)行該方法時(shí)吮旅,F(xiàn)ragment完全不可見溪烤。

onDestroyView():銷毀與Fragment有關(guān)的視圖,但未與Activity解除綁定庇勃,依然可以通過onCreateView方法重新創(chuàng)建視圖檬嘀。通常在ViewPager+Fragment的方式下會(huì)調(diào)用此方法。

onDestroy():銷毀Fragment责嚷。通常按Back鍵退出或者Fragment被回收時(shí)調(diào)用此方法鸳兽。

onDetach():解除與Activity的綁定。在onDestroy方法之后調(diào)用罕拂。

Fragment生命周期執(zhí)行流程(注意紅色的不是生命周期方法):

Fragment創(chuàng)建:setUserVisibleHint()->onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()揍异;

Fragment變?yōu)椴豢梢姞顟B(tài)(鎖屏、回到桌面爆班、被Activity完全覆蓋):onPause()->onSaveInstanceState()->onStop()衷掷;

Fragment變?yōu)椴糠挚梢姞顟B(tài)(打開Dialog樣式的Activity):onPause()->onSaveInstanceState();

Fragment由不可見變?yōu)榛顒?dòng)狀態(tài):onStart()->OnResume()柿菩;

Fragment由部分可見變?yōu)榛顒?dòng)狀態(tài):onResume()戚嗅;

退出應(yīng)用:onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()(注意退出不會(huì)調(diào)用onSaveInstanceState方法,因?yàn)槭侨藶橥顺觯瑳]有必要再保存數(shù)據(jù))渡处;

Fragment被回收又重新創(chuàng)建:被回收?qǐng)?zhí)行onPause()->onSaveInstanceState()->onStop()->onDestroyView()->onDestroy()->onDetach(),重新創(chuàng)建執(zhí)行onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->setUserVisibleHint()祟辟;

橫豎屏切換:與Fragment被回收又重新創(chuàng)建一樣医瘫。

2.創(chuàng)建Fragment

在Activity中添加Fragment。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旧困,一起剝皮案震驚了整個(gè)濱河市醇份,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吼具,老刑警劉巖僚纷,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拗盒,居然都是意外死亡怖竭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門陡蝇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痊臭,“玉大人,你說我怎么就攤上這事登夫」愠祝” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵恼策,是天一觀的道長(zhǎng)鸦致。 經(jīng)常有香客問我,道長(zhǎng)涣楷,這世上最難降的妖魔是什么分唾? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮总棵,結(jié)果婚禮上鳍寂,老公的妹妹穿的比我還像新娘。我一直安慰自己情龄,他們只是感情好迄汛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著骤视,像睡著了一般鞍爱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上专酗,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天睹逃,我揣著相機(jī)與錄音,去河邊找鬼。 笑死沉填,一個(gè)胖子當(dāng)著我的面吹牛疗隶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翼闹,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼斑鼻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了猎荠?” 一聲冷哼從身側(cè)響起坚弱,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎关摇,沒想到半個(gè)月后荒叶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡输虱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年些楣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悼瓮。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戈毒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出横堡,到底是詐尸還是另有隱情埋市,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布命贴,位于F島的核電站道宅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胸蛛。R本人自食惡果不足惜污茵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望葬项。 院中可真熱鬧泞当,春花似錦、人聲如沸民珍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嚷量。三九已至陋桂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝶溶,已是汗流浹背嗜历。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人梨州。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓痕囱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親暴匠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咐蝇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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