Android應用中的三個核心組件:Activities,Services和broadcast receivers都是通過稱爲“Intent”的消息來激活的。Android應用一個特點是“低耦合”,各個Activities,Services和broadcast receivers相當獨立,可以看成是一個個“迷你應用”,而Intent是這些“迷你應用”的粘合劑,Intent不但可以用於同一個Application之間Activities,Services和broadcast receivers的交互,也可以用於不同Application之間Activities,Services和broadcast
receivers的交互。
Intent本身爲一個數據載體,可以描述想要執行的操作以及用於這個操作的數據和其它屬性。用個容易理解的概念,在訪問網站時,我們需要提供網站的URL,有時還需要通過URL參數,在Android世界裏,Intent 的功能類似於URL,Android操作系統根據Intent來觸發對於的Activitives,Services或是Broadcast Receivers。
Android應用中的三個核心組件:Activities,Services和broadcast receivers都是通過Intent來觸發的,當它們觸發的機制各不相同,而且不會有重疊,也就是說發給Activity的Intent不會激活Service或是broadcast receivers,發給broadcast receivers的Intent也不會觸發Activity和Service。
- Activity 通過方法 Context.startActivity() 和 Activity.startActivityForResult()來調用。以函數調用爲參考startActivity() 相當於調用無返回值的函數,startActivityForResult()調用的Activity有返回值,可以通過Activity.setResult()來返回結果。
- Context.startService()用來初始化Service,Context.bindService()可以用來建立與目標Service之間的連接,如果Service沒有運行,則會啓動該Service。
- Broadcast Receiver是通過 Context.sendBroadcast(), Context.sendOrderedBroadcast(), 和Context.sendStickyBroadcast()來觸發的。大部分的Broadcast消息來自於Android操作系統,如電池狀態,來電,短消息等。
和URL不太一樣的是,URL和網站一般是一一對應的,而一個Intent可以用來觸發某個指定的Activity,Service或是Broadcast Receiver,或是觸發多個滿足Intent條件的Activities,Services或是Broadcast Receivers。
下面來看看Android OS如何根據Intent來找到滿足觸發條件的Activity,Service或是Broadcast Receiver. 借用SQL 數據庫的概念可以更好的理解。
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無法查詢到該目標,相當於數據庫中無記錄,即使你在代碼中定義了該Activity,Service或Broadcast Receiver。
Intent
Intent本身爲一個數據載體,可以描述想要執行的操作以及用於這個操作的數據和其它屬性。它主要包含下列信息:
Component name:可以處理該Intent的組件名稱,組件名稱指定義Activity,Service的包和類的全名稱。比如類名爲com.pstreets.gisengine.AndroidGISEngineTutorial ,包名爲com.pstreets.gisengine。 組件名稱爲可選項,如果指定了,意味明確指定用來響應該Intent的Activity,Service。
Action: 列出需要執行的操作名稱。或者在Broadcast Intents的情況下給出發生的事件名稱。
Constant | Target component | Action |
ACTION_CALL | activity | 開始打電話. |
ACTION_EDIT | activity | 顯示編輯對話框. |
ACTION_MAIN | activity | 作爲一個任務(應用)的起始Activity,對於可以從Android應用列表的應用來說,都需要在AndroidManifest.xml 中設置ACTION_MAIN的Intent-Filter屬性。 |
ACTION_SYNC | activity | 同步數據. |
ACTION_BATTERY_LOW | broadcast receiver | 電池電量低告警. |
ACTION_HEADSET_PLUG | broadcast receiver | 耳機插入或拔出. |
ACTION_SCREEN_ON | broadcast receiver | 屏幕打開或關閉. |
ACTION_TIMEZONE_CHANGED | broadcast receiver | 時區變動. |
Data:定義不數據的URL以及數據的MIME類型。不同的Action能夠處理的Data類型也不一樣,比如 ACTION_CALL,它處理的數據格式爲tel: URI,URI爲電話號碼。
Category: 定義了可以響應Intent的附加信息,一個Intent可以指定多個Category類型。和Action類似,Android 預定義了一些Category類型:
Constant | Meaning |
CATEGORY_BROWSABLE |
表示目標Activity可以使用瀏覽器安全顯示指定連接,比如說一個圖片或是Email消息. |
CATEGORY_GADGET |
表示該Activity可以當作一個Gadget嵌入到其它可以放置Gadget的Activity中。 |
CATEGORY_HOME |
表示還Activity是Home Screen,可以設置這個屬性來替換Android自帶的Home Screen。 |
CATEGORY_LAUNCHER |
該Activity可以顯示在Android程序管理器中。一般應用的主Activity都會在AndroidManifest.xml 定義該屬性。 |
Extra: 附加Key-Value列表,可以向目標Activity傳送附加參數。可以理解成函數調用時的參數。
Flags:指出Android啓動目標Activity時的一些選項(比如目標Activity隸屬於那個應用等)。
除非是Intent明確指定目標(Explicitly)Activity的類和包名稱,這是Activity無需在AndroidManifest.xml定義intent-filter,其它情況也叫隱含(Implicit)方式啓動目標Activity,在這種情況下Android 操作系統查找目標Activity,Service或是Broadcast Receiver時主要根據Intent 的Action,Data 和Category屬性來匹配定義在AndroidManifest.xml 中 Activity,Service或是Broadcast Receiver的 Intent Filters。
Intent Filters
Android中沒個有效的Activity,Service,Broadcast Receiver都必須在AndroidManifest.xml有對應的定義。除非只使用明確調用發生來啓動目標Activity,每個Activity都需要定義一個intent-filter。下面是是明確指定目標Activity的示例代碼:
1
2
|
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和數據類型。Android 操作系統就是根據Activity的intent-filter來匹配Intent,從而觸發目標Activity,或是Service,Broadcast Receiver。
最常見的一個Intent Filter組合如下:
<intent-filter . . . >
<action android:name=”code android.intent.action.MAIN” />
<category android:name=”code android.intent.category.LAUNCHER” />
</intent-filter>
表示用戶可以從Android設備的應用程序管理器啓動該Activity,這個Activity爲應用的主Activity,主Activity可以再使用Intent觸發或是啓動其它Activity。