簡(jiǎn)單介紹Android開(kāi)發(fā)中的Activity控件的基本概念
Activity是最基本的模塊,一般稱之為"活動(dòng)",在應(yīng)用程序中,一個(gè)Activity通常就是一個(gè)單獨(dú)的屏幕。簡(jiǎn)單理解,Activity代表一個(gè)用戶所能看到的屏幕,主要用于處理應(yīng)用程序的整體性工作,例如監(jiān)聽(tīng)系統(tǒng)事件,為用戶顯示指定的View,啟動(dòng)其他Activity等。所有應(yīng)用的Activity都繼承于android.app.Activity類,該類是Android提供的基層類,其他的Activity繼承該父類后,通過(guò)父類的方法來(lái)實(shí)現(xiàn)各種功能。
Activity 生命周期圖如下:
在android中,Activity擁有四種基本狀態(tài):
1、Active/Runing一個(gè)新 Activity 啟動(dòng)入棧后,它在屏幕最前端,處于棧的最頂端,此時(shí)它處于可見(jiàn)并可和用戶交互的激活狀態(tài)。
2、Paused 當(dāng) Activity 被另一個(gè)透明或者 Dialog 樣式的 Activity 覆蓋時(shí)的狀態(tài)。此時(shí)它依然與窗口管理器保持連接,系統(tǒng)繼續(xù)維護(hù)其內(nèi)部狀態(tài),所以它仍然可見(jiàn),但它已經(jīng)失去了焦點(diǎn)故不可與用戶交互。
3、Stoped 當(dāng) Activity 被另外一個(gè) Activity 覆蓋、失去焦點(diǎn)并不可見(jiàn)時(shí)處于 Stoped狀態(tài)。
4、Killed Activity 被系統(tǒng)殺死回收或者沒(méi)有被啟動(dòng)時(shí)處于 Killed狀態(tài)。
當(dāng)一個(gè) Activity 實(shí)例被創(chuàng)建、銷毀或者啟動(dòng)另外一個(gè) Activity 時(shí),它在這四種狀態(tài)之間進(jìn)行轉(zhuǎn)換,這種轉(zhuǎn)換的發(fā)生依賴于用戶程序的動(dòng)作。
如上所示,Android 程序員可以決定一個(gè) Activity 的"生",但不能決定它的"死",也就時(shí)說(shuō)程序員可以啟動(dòng)一個(gè) Activity,但是卻不能手動(dòng)的"結(jié)束"一個(gè) Activity。當(dāng)你調(diào)用 Activity.finish()方法時(shí),結(jié)果和用戶按下 BACK 鍵一樣:告訴 Activity Manager 該 Activity 實(shí)例完成了相應(yīng)的工作,可以被"回收"。隨后 Activity Manager 激活處于棧第二層的 Activity 并重新入棧,同時(shí)原 Activity 被壓入到棧的第二層,從 Active 狀態(tài)轉(zhuǎn)到 Paused 狀態(tài)。例如:從 Activity1 中啟動(dòng)了 Activity2,則當(dāng)前處于棧頂端的是 Activity2,第二層是 Activity1,當(dāng)我們調(diào)用 Activity2.finish()方法時(shí),Activity Manager 重新激活 Activity1 并入棧,Activity2 從 Active 狀態(tài)轉(zhuǎn)換 Stoped 狀態(tài),Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被執(zhí)行,Activity2 返回的數(shù)據(jù)通過(guò) data參數(shù)返回給 Activity1。
非用戶行為把a(bǔ)ctivity不可見(jiàn)的時(shí)候,例如電話忽然來(lái)了==
/** * 重新創(chuàng)建恢復(fù)緩存的數(shù)據(jù) */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { Log.i("onRestoreInstanceState",savedInstanceState.getString("name")); super.onRestoreInstanceState(savedInstanceState); } /** * 被摧毀前保存緩存的一些數(shù)據(jù) */ @Override protected void onSaveInstanceState(Bundle outState) { outState.putString("name", "簡(jiǎn)明現(xiàn)代魔法"); super.onSaveInstanceState(outState); }
在android里,有4種activity的啟動(dòng)模式,分別為:
- ·standard: 標(biāo)準(zhǔn)模式,一調(diào)用startActivity()方法就會(huì)產(chǎn)生一個(gè)新的實(shí)例。
- ·singleTop: 如果已經(jīng)有一個(gè)實(shí)例位于Activity棧的頂部時(shí),就不產(chǎn)生新的實(shí)例,而只是調(diào)用Activity中的newInstance()方法。如果不位于棧頂,會(huì)產(chǎn)生一個(gè)新的實(shí)例。
- ·singleTask: 會(huì)在一個(gè)新的task中產(chǎn)生這個(gè)實(shí)例,以后每次調(diào)用都會(huì)使用這個(gè),不會(huì)去產(chǎn)生新的實(shí)例了。
- ·singleInstance: 這個(gè)跟singleTask基本上是一樣,只有一個(gè)區(qū)別:在這個(gè)模式下的Activity實(shí)例所處的task中,只能有這個(gè)activity實(shí)例,不能有其他的實(shí)例。
這些啟動(dòng)模式可以在功能清單文件AndroidManifest.xml中進(jìn)行設(shè)置,中的launchMode屬性。
相關(guān)的代碼中也有一些標(biāo)志可以使用,比如我們想只啟用一個(gè)實(shí)例,則可以使用 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 標(biāo)志,這個(gè)標(biāo)志表示:如果這個(gè)activity已經(jīng)啟動(dòng)了,就不產(chǎn)生新的activity,而只是把這個(gè)activity實(shí)例加到棧頂來(lái)就可以了。
Intent intent = new Intent(ReorderFour.this, ReorderTwo.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent);
Activity的加載模式受啟動(dòng)Activity的Intent對(duì)象中設(shè)置的Flag和manifest文件中Activity的元素的特性值交互控制。
下面是影響加載模式的一些特性
核心的Intent Flag有:
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- FLAG_ACTIVITY_SINGLE_TOP
核心的特性有:
- taskAffinity
- launchMode
- allowTaskReparenting
- clearTaskOnLaunch
- alwaysRetainTaskState
- finishOnTaskLaunch
四種加載模式的區(qū)別
所屬task的區(qū)別
一般情況下,“standard”和”singleTop”的activity的目標(biāo)task,和收到的Intent的發(fā)送者在同一個(gè)task內(nèi),就相當(dāng)于誰(shuí)調(diào)用它,它就跟誰(shuí)在同一個(gè)Task中。
除非Intent包括參數(shù)FLAG_ACTIVITY_NEW_TASK。如果提供了FLAG_ACTIVITY_NEW_TASK參數(shù),會(huì)啟動(dòng)到別的task里。
“singleTask”和”singleInstance” 總是把要啟動(dòng)的activity作為一個(gè)task的根元素,他們不會(huì)被啟動(dòng)到一個(gè)其他task里。
是否允許多個(gè)實(shí)例
“standard”和”singleTop”可以被實(shí)例化多次,并且是可以存在于不同的task中;這種實(shí)例化時(shí)一個(gè)task可以包括一個(gè)activity的多個(gè)實(shí)例;
“singleTask”和”singleInstance”則限制只生成一個(gè)實(shí)例,并且是task的根元素。
singleTop 要求如果創(chuàng)建intent的時(shí)候棧頂已經(jīng)有要?jiǎng)?chuàng)建的Activity的實(shí)例,則將intent發(fā)送給該實(shí)例,而不創(chuàng)建新的實(shí)例。
是否允許其它activity存在于本task內(nèi)
“singleInstance”獨(dú)占一個(gè)task,其它activity不能存在那個(gè)task里;
如果它啟動(dòng)了一個(gè)新的activity,不管新的activity的launch mode 如何,新的activity都將會(huì)到別的task里運(yùn)行(如同加了FLAG_ACTIVITY_NEW_TASK參數(shù))。
而另外三種模式,則可以和其它activity共存。
是否每次都生成新實(shí)例
“standard”對(duì)于每一個(gè)啟動(dòng)Intent都會(huì)生成一個(gè)activity的新實(shí)例;
“singleTop”的activity如果在task的棧頂?shù)脑挘瑒t不生成新的該activity的實(shí)例,直接使用棧頂?shù)膶?shí)例,否則,生成該activity的實(shí)例。
比如:
現(xiàn)在task棧元素為A-B-C-D(D在棧頂),這時(shí)候給D發(fā)一個(gè)啟動(dòng)intent,如果D是 “standard”的,則生成D的一個(gè)新實(shí)例,棧變?yōu)锳-B-C-D-D。
如果D是singleTop的話,則不會(huì)生產(chǎn)D的新實(shí)例,棧狀態(tài)仍為A-B-C-D
如果這時(shí)候給B發(fā)Intent的話,不管B的launchmode是”standard” 還是 “singleTop” ,都會(huì)生成B的新實(shí)例,棧狀態(tài)變?yōu)锳-B-C-D-B。
“singleInstance”是其所在棧的唯一activity,它會(huì)每次都被重用。
“singleTask” 如果在棧頂,則接受intent,否則,該intent會(huì)被丟棄,但是該task仍會(huì)回到前臺(tái)。 當(dāng)已經(jīng)存在的activity實(shí)例處理新的intent時(shí)候,會(huì)調(diào)用onNewIntent()方法,如果收到intent生成一個(gè)activity實(shí)例,那么用戶可以通過(guò)back鍵回到上一個(gè)狀態(tài);如果是已經(jīng)存在的一個(gè)activity來(lái)處理這個(gè)intent的話,用戶不能通過(guò)按back鍵返回到這之前的狀態(tài)。
- Android的Activity加載方式實(shí)例分析
- Android編程之四種Activity加載模式分析
- Android編程四大組件之Activity用法實(shí)例分析
- 深入解讀Android開(kāi)發(fā)中Activity的生命周期
- Android編程獲取并設(shè)置Activity亮度的方法
- Android編程中activity的完整生命周期實(shí)例詳解
- Android編程之Activity中onDestroy()調(diào)用分析
- Android編程實(shí)現(xiàn)兩個(gè)Activity之間共享數(shù)據(jù)及互相訪問(wèn)的方法
- Android實(shí)現(xiàn)Activity之間通信的方法
- Android Activity中onStart()和onResume()的區(qū)別分析
相關(guān)文章
Android 個(gè)人理財(cái)工具三:添加賬單頁(yè)面 上
本文主要介紹Android 個(gè)人理財(cái)工具添加賬單頁(yè)面的功能實(shí)現(xiàn),這里提供實(shí)例代碼和實(shí)現(xiàn)效果圖,有興趣的小伙伴可以參考下2016-08-08Android之日期及時(shí)間選擇對(duì)話框用法實(shí)例分析
這篇文章主要介紹了Android之日期及時(shí)間選擇對(duì)話框用法,以實(shí)例形式較為詳細(xì)的分析了Android創(chuàng)建日期及時(shí)間選擇對(duì)話框的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09Android ViewPager實(shí)現(xiàn)圖片輪播效果
這篇文章主要為大家詳細(xì)介紹了Android ViewPager實(shí)現(xiàn)圖片輪播效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Android開(kāi)發(fā)筆記之:深入理解多線程AsyncTask
本篇文章是對(duì)Android中多線程AsyncTask進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Android Studio 當(dāng)build時(shí)候出錯(cuò)解決辦法
這篇文章主要介紹了 Android Studio在build的時(shí)候出現(xiàn)transformClassesWithDexForDebug錯(cuò)誤解決辦法的相關(guān)資料,需要的朋友可以參考下2017-05-05Android中Activity啟動(dòng)默認(rèn)不顯示輸入法解決方法
這篇文章主要介紹了Android中Activity啟動(dòng)默認(rèn)不顯示輸入法解決方法,一般是因?yàn)榘琧heckbox控件導(dǎo)致Activity啟動(dòng)默認(rèn)不顯示輸入法,本文給出了正確解決方法,需要的朋友可以參考下2015-06-06Android編程之監(jiān)聽(tīng)器的實(shí)現(xiàn)方法
這篇文章主要介紹了Android編程之監(jiān)聽(tīng)器的實(shí)現(xiàn)方法,以實(shí)例形式較為詳細(xì)的分析了Android監(jiān)聽(tīng)器的創(chuàng)建、注冊(cè)及相關(guān)使用技巧,需要的朋友可以參考下2015-11-11Android selector狀態(tài)選擇器的使用詳解
這篇文章主要為大家詳細(xì)介紹了Android selector狀態(tài)選擇器的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09