1. 簡介
Activity是Android四大組件之一,為用戶提供與系統(tǒng)交互的界面总珠,每一個應(yīng)用都有一個或者多個Acticity
2.生命周期
Activity生命周期的回調(diào)主要有onCreate()产雹、onRestart()、onStart()浓恶、onResume()紧憾、onPause()、onStop()签夭、onDestory()這幾個方法齐邦,Activity的生命周期類別主要分為三種,如下第租。
整個生命周期措拇,Activity完整生命周期發(fā)生在onCreate()和onDestroy()之間。在onCreate()中執(zhí)行一些全局性的設(shè)置(例如設(shè)置布局文件煌妈,初始化View等等),在onDestroy()中釋放所有資源
可見生命周期宣羊,Activity可見生命周期發(fā)生在onStart()和onStop()之間璧诵,在這段時間內(nèi),用戶可以在屏幕上看見Activity并與之交互仇冯。在整個生命周期之宿,Activity對用戶可見和隱藏兩種狀態(tài)可能交替出現(xiàn),系統(tǒng)就會多次調(diào)用onStart()和onStop()方法苛坚。
前臺生命周期比被,Activity的前臺生命周期發(fā)生在onResume()和onPause()之間,在這段時間內(nèi)泼舱,Activity位于屏幕上其他Activiy之前等缀,而且獲取屏幕的焦點。Activity可能頻繁的轉(zhuǎn)入或轉(zhuǎn)出前臺娇昙,例如當設(shè)備休眠或者彈出對話框時尺迂,系統(tǒng)會調(diào)用onPause()方法。因為此狀態(tài)可能經(jīng)常發(fā)生變化冒掌,所以在這兩個方法中建議做一些輕量級操作噪裕。
Activity生命周期圖如下:
圖-1 Activity生命周期
3.intent
被啟動的Activity必須要在AndroidManifest.xml文件中聲明,否則會拋出異常股毫。
正常啟動一個Activity的代碼如下:
// 顯示啟動Intent intent =newIntent(this, MyActivity.class);
// 設(shè)置傳遞的數(shù)據(jù)intent.put(KEY_NAME, value);
startActivity(intent);
// 隱式啟動Intent intent =newIntent(ACTION_NAME);
//隱式啟動
// 要將textMessage信息分享出去
Intent sendIntent=newIntent();sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
// 設(shè)置其他匹配規(guī)則...// 設(shè)置傳遞的數(shù)據(jù)膳音,bundle數(shù)據(jù)集intent.putExtras(bundle);startActivity(intent);
4.啟動其他Activity時候生命周期協(xié)調(diào)
當一個Activity A去啟動一個新的Activity B時候,A和B的生命周期并不是依次進行铃诬,也就是說它們的生命周期會有所重疊祭陷。在創(chuàng)建B的時候苍凛,A不會完全停止,更確切的說颗胡,啟動B的過程與A停止的過程會有重疊毫深。所以A和B生命周期回調(diào)的順序就很重要了,回調(diào)順序如下毒姨。
Activity A的onPause()方法執(zhí)行
Activity B的onCreate()哑蔫、onStart()、onResume()方法依次執(zhí)行弧呐。onResume()方法執(zhí)行后闸迷,Activity B獲取屏幕焦點
Activity A的onStop()方法執(zhí)行
在知道了從一個Activity到另一個Activity轉(zhuǎn)變時候生命周期的順序,平時研發(fā)時候就需要注意了俘枫。例如腥沽,當必須在第一個Activity停止之前存儲數(shù)據(jù),以便下一個Activity能夠使用鸠蚪,應(yīng)該在onPause()方法中儲存而不是onStop()方法中今阳。
5.?啟動模式
一個應(yīng)用一般包含很多Activity,它們按照各自打開的順序排列在返回棧(Back Stack)中茅信,這些Activity統(tǒng)稱為Task盾舌。大多數(shù)Task的起點是用戶在屏幕中點擊應(yīng)用圖標啟動應(yīng)用,該應(yīng)用的Task出現(xiàn)在前臺蘸鲸,如果該應(yīng)用沒有Task妖谴,也就是最近未被打開,則會新建一個Task酌摇,并且會將該應(yīng)用的MainActivity加入返回棧中膝舅,作為返回棧中的根Activity。
通常情況下窑多,當前一個Activity啟動一個新的Activity時候仍稀,新的Activity會被加入返回棧中,并處于棧頂埂息,獲取屏幕焦點琳轿,而前一個Activity仍保留在返回棧中,處于停止(onStop)狀態(tài)耿芹。 Activity停止時崭篡,如上所說,系統(tǒng)會保存其頁面狀態(tài)吧秕。當用戶返回時候琉闪,當前處于棧頂?shù)腁ctivity會從返回棧中彈出,并被銷毀(onDestroy)砸彬,恢復(fù)前一個Activity的狀態(tài)颠毙。返回棧中的Activity永遠不會重新排列斯入,遵循先進后出的原則。
圖-3 Activity出入返回棧
上述講的只是標準的Activity與返回棧的關(guān)系蛀蜜,在Android中Activity有四種啟動模式刻两,分別是standard、singleTop滴某、singleTask磅摹、singleInstance。
6啟動模式
我們可以通過在AndroidManifest.xml配置Activity的啟動模式霎奢。
或者在代碼中向Intent添加相應(yīng)標志户誓。
Intent intent =newIntent(this, MyActivity.class);? intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);? startActivity(intent);
注:第二種方法設(shè)置啟動模式的優(yōu)先級高于第一種,如果兩者都存在幕侠,以第二種為準帝美。
6.2standard(默認模式)
默認的啟動模式,新啟動的Activity放入返回棧棧頂晤硕,遵循先進后出原則悼潭,同一個Activity可以被實例化多次。
6.3singleTop
如果當前返回棧的頂部不存在該Activity舞箍,則新建該Activity并放入棧頂舰褪;
如果當前返回棧的頂部已存在Activity的一個實例,則系統(tǒng)會通過調(diào)用該實例的onNewIntent()方法向其傳送Intent创译,不創(chuàng)建該Activity的新實例抵知。
6.4singleTask
如果該Activity需要的返回棧是A墙基,但是當前系統(tǒng)中不存在A返回棧软族,系統(tǒng)會新建返回棧A,然后再創(chuàng)建該Activity實例將其壓入返回棧中残制。
如果該Activity需要的返回棧存在立砸,而且返回棧中沒有該Activity,則新建Activity并放入Task棧頂
如果該Activity需要的返回棧存在初茶,而且返回棧中有該Activity
如果該Activity在棧頂颗祝,調(diào)用其onNewIntent()方法傳入Intent
如果該Activity不在棧頂,彈出其上面的所有Activity恼布,讓該Activity置于棧頂螺戳,并調(diào)用其onNewIntent()方法傳入Intent
默認情況下,所有Activity所需要的返回棧名稱為應(yīng)用的包名折汞,我們可以在AndroidManifest.xml中通過設(shè)置Activity的android:taskAffinity屬性來指定該Activity需要的返回棧名稱倔幼,這個名稱不能和應(yīng)用包名相同,否則相當于沒有指定爽待。taskAffinity翻譯過來是返回棧親和性损同,我個人理解這個屬性是指定與返回棧親和度或者優(yōu)先級翩腐,并不是每次都會新建返回棧。注意一般android:taskAffinity屬性和singleTask一起使用才有意義膏燃,會新建返回棧茂卦,如果只是指定了android:taskAffinity屬性但是依然是singleTop和standard模式,新啟動的Activity依然會在原來的返回棧中组哩。
6.5singleInstance
系統(tǒng)創(chuàng)建一個新的Task并創(chuàng)建Activity的新實例置于新Task返回棧中等龙,但是系統(tǒng)不會將任何其他Activity的實例放入這個新建的Task中。該Activity始終是其Task唯一僅有的成員禁炒,由此Activity啟動的任何Activity而咆,如果沒有指定返回棧名稱,則新啟動的Activity放入默認的返回棧幕袱;如果指定了返回棧名稱暴备,則將新啟動的Activity放入指定的返回棧中。
6.6Activity任務(wù)棧
Android中返回棧分為前臺返回棧和后臺返回棧们豌,前臺返回棧是指返回棧棧頂?shù)腁ctivity正在和用戶進行交互涯捻。
上面說了幾種啟動模式,下面看一下幾種啟動模式混合時候返回棧調(diào)度情況望迎,我個人的理解和官方有些不同障癌,這個大家可以跳過,去看官方的介紹辩尊。
個人理解一個應(yīng)用創(chuàng)建的默認返回棧為基準涛浙,按返回鍵時候,根據(jù)返回棧創(chuàng)建順序依次清空返回棧摄欲,當默認返回棧清空時候轿亮,應(yīng)用也就關(guān)閉了,但是有些后臺返回棧中的Activity并不會立即銷毀胸墙。
下面列出幾種特殊情況的返回棧書序調(diào)用圖我注。
情況一
Activity A和Activity B為默認啟動模式,未設(shè)置taskAffinity屬性迟隅。
Activity C啟動模式是singleTask但骨,設(shè)置了taskAffinity屬性。
啟動順序是Activity A -> Activity B -> Activity C
看一下返回棧調(diào)用情況:
圖-4 返回棧圖1
- 情況二 Activity A和Activity B為默認啟動模式智袭,A未設(shè)置taskAffinity屬性奔缠,B設(shè)置taskAffinity屬性為默認返回棧。 Activity C和Activity D啟動模式是singleTask吼野,設(shè)置了相同的taskAffinity屬性校哎。 啟動順序是`Activity A -> Activity C -> Activity D -> Activity B` 返回棧調(diào)用情況如下圖:
圖-5 返回棧圖2
官方圖,這里注意一下箫锤,官方圖中在`StartActivity Y`后贬蛙,Y與X所在返回棧和1與2所在的返回棧是不同的雨女,他們并不在同一個返回棧:
圖-6 返回棧圖3
- 情況三 Activity A和Activity C為默認啟動模式,未設(shè)置taskAffinity屬性 Activity B啟動模式是singleInstance 啟動順序是`Activity A -> Activity B -> Activity C` 返回棧調(diào)用情況如下圖:
圖-7 返回棧圖4/div> **注:按返回鍵和啟動Activity從返回棧A到返回棧B結(jié)果是不同的阳准,按返回鍵時候氛堕,會首先彈出返回棧A中的Activity,等到返回棧沒有Activity時候野蝇,才會進入另一個返回棧讼稚,這個時候返回棧A已經(jīng)沒有Activity了。**