Android 應(yīng)用中的三個(gè)核心組件:Activities,Services 和 broadcast receivers 都是通過稱為“Intent”的消息來激活的。Android 應(yīng)用一個(gè)特點(diǎn)是“低耦合”,各個(gè) Activities,Services 和broadcast receivers 相當(dāng)獨(dú)立,可以看成是一個(gè)個(gè)“迷你應(yīng)用”,而 Intent 是這些“迷你應(yīng)用”的粘合劑,Intent 不但可以用于同一個(gè) Application 之間 Activities,Services 和 broadcast receivers 的交互,也可以用于不同 Application 之間 Activities,Services 和 broadcast receivers 的交互。 Intent 本身為一個(gè)數(shù)據(jù)載體,可以描述想要執(zhí)行的操作以及用于這個(gè)操作的數(shù)據(jù)和其它屬性。用個(gè)容易理解的概念,在訪問網(wǎng)站時(shí),我們需要提供網(wǎng)站的URL,有時(shí)還需要通過 URL 參數(shù),在 Android 世界里,Intent 的功能類似于 URL,Android 操作系統(tǒng)根據(jù) Intent 來觸發(fā)對(duì)于的Activitives,Services 或是 Broadcast Receivers。
Android 應(yīng)用中的三個(gè)核心組件:Activities,Services 和 broadcast receivers 都是通過Intent 來觸發(fā)的,當(dāng)它們觸發(fā)的機(jī)制各不相同,而且不會(huì)有重疊,也就是說發(fā)給 Activity 的 Intent 不會(huì)激活 Service 或是 broadcast receivers,發(fā)給 broadcast receivers 的 Intent 也不會(huì)觸發(fā) Activity 和 Service。
和URL不太一樣的是,URL 和網(wǎng)站一般是一一對(duì)應(yīng)的,而一個(gè) Intent 可以用來觸發(fā)某個(gè)指定的Activity,Service 或是 Broadcast Receiver,或是觸發(fā)多個(gè)滿足 Intent 條件的 Activities,Services 或是 Broadcast Receivers。
下面來看看 Android OS 如何根據(jù) Intent 來找到滿足觸發(fā)條件的 Activity,Service 或是Broadcast Receiver. 借用 SQL 數(shù)據(jù)庫(kù)的概念可以更好的理解。
SELECT (Activitives|Services|Broadcast Receivers) AS Target
FROM (List in AndroidManifest.xml)
WHERE Intent Meet Target’s (Intent Filter)
意思就是從 AndroidManifest.xml 中定義的 Activities,Services 和 Broadcast Receiver 列表中查找符合 Intent 條件的 Activities,Services,或是 Broadcast Receivers。所有能活被激活的 Activity,Service 和 Broadcast Receiver 都必須在 AndroidManifest.xml 有定義,否則 Android OS 無法查詢到該目標(biāo),相當(dāng)于數(shù)據(jù)庫(kù)中無記錄,即使你在代碼中定義了該Activity,Service 或 Broadcast Receiver。
Intent
Intent 本身為一個(gè)數(shù)據(jù)載體,可以描述想要執(zhí)行的操作以及用于這個(gè)操作的數(shù)據(jù)和其它屬性。它主要包含下列信息:
Component name:可以處理該 Intent 的組件名稱,組件名稱指定義 Activity,Service 的包和類的全名稱。比如類名為 com.pstreets.gisengine.AndroidGISEngineTutorial,包名為 com.pstreets.gisengine。 組件名稱為可選項(xiàng),如果指定了,意味明確指定用來響應(yīng)該 Intent 的 Activity,Service。
Action: 列出需要執(zhí)行的操作名稱?;蛘咴?Broadcast Intents 的情況下給出發(fā)生的事件名稱。
| Constant | Target component | Action |
|---|---|---|
| ACTION_CALL | activity | 開始打電話. |
| ACTION_EDIT | activity | 顯示編輯對(duì)話框. |
| ACTION_MAIN | activity | 作為一個(gè)任務(wù)(應(yīng)用)的起始 Activity,對(duì)于可以從 Android 應(yīng)用列表的應(yīng)用來說,都需要在 AndroidManifest.xml 中設(shè)置 ACTION_MAIN 的 Intent-Filter 屬性。 |
| ACTION_SYNC | activity | 同步數(shù)據(jù). |
| ACTION_BATTERY_LOW | broadcast receiver | 電池電量低告警. |
| ACTION_HEADSET_PLUG | broadcast receiver | 耳機(jī)插入或拔出. |
| ACTION_SCREEN_ON | broadcast receiver | 屏幕打開或關(guān)閉. |
| ACTION_TIMEZONE_CHANGED | broadcast receiver | 時(shí)區(qū)變動(dòng). |
Data:定義不數(shù)據(jù)的 URL 以及數(shù)據(jù)的 MIME 類型。不同的 Action 能夠處理的 Data 類型也不一樣,比如 ACTION_CALL,它處理的數(shù)據(jù)格式為 tel: URI,URI 為電話號(hào)碼。 Category: 定義了可以響應(yīng) Intent 的附加信息,一個(gè) Intent 可以指定多個(gè) Category 類型。和 Action 類似,Android 預(yù)定義了一些 Category 類型:
| Constant | Meaning |
|---|---|
| CATEGORY_BROWSABLE | 表示目標(biāo) Activity 可以使用瀏覽器安全顯示指定連接,比如說一個(gè)圖片或是 Email 消息. |
| CATEGORY_GADGET | 表示該 Activity 可以當(dāng)作一個(gè) Gadget 嵌入到其它可以放置 Gadget 的 Activity 中。 |
| CATEGORY_HOME | 表示還 Activity 是 Home Screen,可以設(shè)置這個(gè)屬性來替換 Android 自帶的 Home Screen。 |
| CATEGORY_LAUNCHER | 該 Activity 可以顯示在 Android 程序管理器中。一般應(yīng)用的主 Activity 都會(huì)在 AndroidManifest.xml 定義該屬性。 |
Extra: 附加 Key-Value 列表,可以向目標(biāo) Activity 傳送附加參數(shù)??梢岳斫獬珊瘮?shù)調(diào)用時(shí)的參數(shù)。
Flags:指出 Android 啟動(dòng)目標(biāo) Activity 時(shí)的一些選項(xiàng)(比如目標(biāo) Activity 隸屬于那個(gè)應(yīng)用等)。
除非是 Intent 明確指定目標(biāo)(Explicitly)Activity 的類和包名稱,這是 Activity 無需在 AndroidManifest.xml 定義 intent-filter,其它情況也叫隱含(Implicit)方式啟動(dòng)目標(biāo) Activity,在這種情況下 Android 操作系統(tǒng)查找目標(biāo) Activity,Service 或是 Broadcast Receiver 時(shí)主要根據(jù) Intent 的 Action,Data 和 Category 屬性來匹配定義在 AndroidManifest.xml 中 Activity,Service 或是 Broadcast Receiver 的 Intent Filters。
Intent Filters
Android 中沒個(gè)有效的 Activity,Service,Broadcast Receiver 都必須在 AndroidManifest.xml 有對(duì)應(yīng)的定義。除非只使用明確調(diào)用發(fā)生來啟動(dòng)目標(biāo) Activity,每個(gè) Activity 都需要定義一個(gè) intent-filter。下面是是明確指定目標(biāo)Activity 的示例代碼:
Intent intent=new Intent(SplashActivity.this,GNavigator.class);
startActivity(intent);
而更一般的情況,Activity 在 AndroidManifest.xml 具有如下定義:
<activity android:name=”.AndroidGISEngineTutorial”
android:label=”@string/app_name”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<action android:name=”com.example.project.SHOW_CURRENT” />
<action android:name=”com.example.project.SHOW_RECENT” />
<action android:name=”com.example.project.SHOW_PENDING” />
….
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
…
<data android:mimeType=”video/mpeg” android:scheme=”http” . . . />
<data android:mimeType=”audio/mpeg” android:scheme=”http” . . . />
….
</intent-filter>
</activity>
Activity 的 intent-filter 可以包含 action,category,data 子元素,給出了該 Activity 能夠處理的 Intent 的Action,Category 和數(shù)據(jù)類型。Android 操作系統(tǒng)就是根據(jù) Activity 的 intent-filter 來匹配 Intent,從而觸發(fā)目標(biāo)Activity,或是 Service,Broadcast Receiver。
最常見的一個(gè) Intent Filter 組合如下:
<intent-filter . . . >
<action android:name=”code android.intent.action.MAIN” />
<category android:name=”code android.intent.category.LAUNCHER” />
</intent-filter>
表示用戶可以從 Android 設(shè)備的應(yīng)用程序管理器啟動(dòng)該 Activity,這個(gè) Activity 為應(yīng)用的主 Activity,主 Activity可以再使用 Intent 觸發(fā)或是啟動(dòng)其它 Activity。