前言
Android四大組件有Activity、service、Content Provider、BroadcastReceiver。Activity是Android組件中最基本也是最為常見用的四大組件之一,其重要程度可想而知。對(duì)于大部分Android開發(fā)者來說,都可以輕松的使用它。但是在這篇文章中,我想深入的探索Activity。從而更好的從事開發(fā)工作。
概念
Activity是一個(gè)應(yīng)用組件,用戶可與其提供的屏幕進(jìn)行交互,以執(zhí)行撥打電話、拍攝照片、發(fā)送電子郵件或查看地圖等操作。 每個(gè) Activity 都會(huì)獲得一個(gè)用于繪制其用戶界面的窗口。窗口通常會(huì)充滿屏幕,但也可小于屏幕并浮動(dòng)在其他窗口之上。
Activity 基本上以三種狀態(tài)存在:
| 狀態(tài) | 描述 |
|---|---|
| 繼續(xù) | 此 Activity 位于屏幕前臺(tái)并具有用戶焦點(diǎn)。(有時(shí)也將此狀態(tài)稱作“運(yùn)行中”。) |
| 暫停 | 另一個(gè) Activity 位于屏幕前臺(tái)并具有用戶焦點(diǎn),但此 Activity 仍可見。也就是說,另一個(gè) Activity 顯示在此 Activity 上方,并且該 Activity 部分透明或未覆蓋整個(gè)屏幕。 暫停的 Activity 處于完全活動(dòng)狀態(tài)Activity對(duì)象保留在內(nèi)存中,它保留了所有狀態(tài)和成員信息,并與窗口管理器保持連接),但在內(nèi)存極度不足的情況下,可能會(huì)被系統(tǒng)終止。 |
| 停止 | 該 Activity 被另一個(gè) Activity 完全遮蓋(該 Activity 目前位于“后臺(tái)”)。 已停止的 Activity 同樣仍處于活動(dòng)狀態(tài)(Activity對(duì)象保留在內(nèi)存中,它保留了所有狀態(tài)和成員信息,但未與窗口管理器連接)。 不過,它對(duì)用戶不再可見,在他處需要內(nèi)存時(shí)可能會(huì)被系統(tǒng)終止。 |
如果 Activity 處于暫?;蛲V?fàn)顟B(tài),系統(tǒng)可通過要求其結(jié)束(調(diào)用
finish()
方法)或直接終止其進(jìn)程,將其從內(nèi)存中刪除。(將其結(jié)束或終止后)再次打開 Activity 時(shí),必須重建。
生命周期

這是一張經(jīng)典的Activity生命周期圖,詳細(xì)而直觀得表現(xiàn)了Activity各生命周期間的關(guān)系 。那么下圖 列出了相同的生命周期回調(diào)方法,其中對(duì)每一種回調(diào)方法做了更詳細(xì)的描述,并說明了每一種方法在 Activity 整個(gè)生命周期內(nèi)的位置,包括在回調(diào)方法完成后系統(tǒng)能否終止 Activity。

這些方法共同定義 Activity 的整個(gè)生命周期。您可以通過實(shí)現(xiàn)這些方法監(jiān)控 Activity 生命周期中的三個(gè)嵌套循環(huán):
Activity 的整個(gè)生命周期發(fā)生在
onCreate()調(diào)用與onDestroy()調(diào)用之間。Activity 應(yīng)在onCreate()中執(zhí)行“全局”狀態(tài)設(shè)置(例如初始化View);在onDestroy()中釋放資源(例如調(diào)用unregisterReceiver)。Activity 的可見生命周期發(fā)生在
onStart()調(diào)用與onStop()調(diào)用之間。在這段時(shí)間,用戶可以在屏幕上看到 Activity 并與其交互。 在 Activity 的整個(gè)生命周期,當(dāng) Activity 在對(duì)用戶可見和隱藏兩種狀態(tài)中交替變化時(shí),系統(tǒng)可能會(huì)多次調(diào)用onStart()和onStop()。Activity 的前臺(tái)生命周期發(fā)生在
onResume()調(diào)用與onPause()調(diào)用之間。在這段時(shí)間,Activity 位于屏幕上的所有其他 Activity 之前,并具有用戶輸入焦點(diǎn)。 Activity 可頻繁轉(zhuǎn)入和轉(zhuǎn)出前臺(tái)。由于此狀態(tài)可能經(jīng)常發(fā)生轉(zhuǎn)變,因此這兩個(gè)方法中應(yīng)采用適度輕量級(jí)的代碼,以避免因轉(zhuǎn)變速度慢而讓用戶等待。
啟動(dòng)方式
Activity的啟動(dòng)方式有兩種方式:顯示調(diào)用和隱式調(diào)用。靈活的運(yùn)用這兩種能使您的APP更加方便快捷,提高用戶體驗(yàn)。
顯示調(diào)用
顯示調(diào)用:通過指定組件名稱來實(shí)現(xiàn)的,它一般用在知道目標(biāo)組件名稱的前提下,一般是在相同的應(yīng)用程序內(nèi)部實(shí)現(xiàn)的。
直接啟動(dòng)Activity
//通過Activity名啟動(dòng)
Intent intent=new Intent(MainActivity.this,SettingActivity.class);
intent.putExtra(NAME,nameText);
startActivity(intent);
//通過包名和Activity名啟動(dòng)
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName componentName = new ComponentName("com.zxm.demo","com.zxm.demo.MainActivity");
intent.setComponent(componentName );
startActivity(intent);
啟動(dòng)Activity以獲取結(jié)果
private void pickContact() {
Intent intent = new Intent(OneActivity.this,SecondActivity.class);
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) {
//Data received: data.getData()
}
}
隱式調(diào)用
隱式調(diào)用:通過Intent Filter來實(shí)現(xiàn)的,Android系統(tǒng)會(huì)根據(jù)隱式意圖中設(shè)置的動(dòng)作(action)、類別(category)、數(shù)據(jù)(URI和數(shù)據(jù)類型)找到最合適的組件來處理這個(gè)意圖。一般是用于在不同應(yīng)用程序之間。
設(shè)置數(shù)據(jù)
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
Uri uri = Uri.parse(Uri.parser("host//:scheme?param"));
intent.setData(uri);
activity.startActivity(intent);
對(duì)應(yīng)的AndroidManifest.xml中的IntentFilter添加相應(yīng)的配置
<activity
android:name="com.zxm.demo.SecondActivity"
android:label="@string/app_name" >
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="host"
android:scheme="scheme" />
</intent-filter>
</activity>
設(shè)置類別
如果Intent中的存在category那么所有的category都必須和Activity過濾規(guī)則中的category相同。才能和這個(gè)Activity匹配。Intent中的category數(shù)量可能少于Activity中配置的category數(shù)量,但是Intent中的這category必須和Activity中配置的category相同才能匹配。這里注意,值設(shè)置類別是不能啟動(dòng)成功的,必須要
Intent intent = new Intent();
intent.addCategory("com.zxm.category.type_1");
intent.setAction("android.intent.action.SEND");
startActivity(intent);
對(duì)應(yīng)的AndroidManifest.xml中的IntentFilter添加相應(yīng)的配置
<activity
android:name="com.zxm.demo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<category android:name="android.intent.action.SEND" />
<category android:name="com.zxm.category.type_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
設(shè)置動(dòng)作
Intent中的Action必須能夠和Activity過濾規(guī)則中的Action匹配.(這里的匹配是完全相等). 一個(gè)過濾規(guī)則中有多個(gè)action,那么只要Intent中的action能夠和Activity過濾規(guī)則中的任何一個(gè)action相同即可匹配成功。
Intent intent = new Intent();
//設(shè)置Intent的Action屬性
intent.setAction("android.intent.action.SEND");
startActivity(intent);
<activity
android:name="com.zxm.demo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<category android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
啟動(dòng)模式(LaunchMode)
Activity的啟動(dòng)模式有四種:standard、singleTop、singleTask、singleInstance。
想搞清楚啟動(dòng)模式,首先我們要搞清楚什么是任務(wù)棧(TaskAffinity)。
TaskAffinity 參數(shù)標(biāo)識(shí)著Activity所需要的任務(wù)棧的名稱,默認(rèn)情況下,一個(gè)應(yīng)用中所有Activity所需要的任務(wù)棧名稱都為該應(yīng)用的包名。
TaskAffinity 屬性一般跟singleTask模式或者跟allowTaskReparenting屬性結(jié)合使用,在其他情況下沒有實(shí)際意義。
standard:標(biāo)準(zhǔn)模式,這是系統(tǒng)默認(rèn)的默認(rèn)。在這種模式下不管之前有沒有Activity實(shí)例,每一次啟動(dòng)Activity都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例,并置于Activity任務(wù)棧棧頂。
singleTop:棧頂復(fù)用模式。這個(gè)模式下,如果棧頂存在該Activity的實(shí)例,那么這個(gè)Activity不會(huì)被重寫創(chuàng)建,同時(shí)它的
onNewIntent()方法會(huì)被調(diào)用。如果棧頂不存在該Activity的實(shí)例,則情況與standard模式相同。注意的如果Activity已經(jīng)存在它的onCreate(),onStart()方法不會(huì)被調(diào)用。singleTask:棧內(nèi)復(fù)用模式。在這種模式下,只要Activity存在棧內(nèi),那么多次啟動(dòng)這個(gè)Activity都不會(huì)重新創(chuàng)建實(shí)例,直接使用這個(gè)實(shí)例,并且將該實(shí)例以上的Activity全部清除,同時(shí)系統(tǒng)會(huì)調(diào)用它的
onNewIntent()方法。singleInstance:全局唯一模式, 該模式具備singleTask模式的所有特性外,與它的區(qū)別就是,這種模式下的Activity會(huì)單獨(dú)占用一個(gè)Task棧,具有全局唯一性。如果在啟動(dòng)這樣的Activiyt時(shí),已經(jīng)存在了一個(gè)實(shí)例,那么會(huì)把它所在的任務(wù)調(diào)度到前臺(tái),重用這個(gè)實(shí)例。
小結(jié)
關(guān)于Activity的知識(shí)還有很多,相信大家如果弄懂了以上這些點(diǎn),會(huì)跟好的把握和掌控項(xiàng)目。文章參考了AndroidAPI指南。 如有不足之處,希望多多指出。