http://www.cnblogs.com/XP-Lee/p/3613830.html
Intent就是一個啟用元件的訊息物件,用於元件之間的通訊。需要注意的是,能被Intent啟用通訊的元件只有三類:Activity、Service和BroadcastReceiver。對應這三類元件,Intent
有下面三種使用場景:
- 啟動Activity:在app中,一個Activity就代表一個使用者介面。以
Intent
為引數呼叫startActivity()啟動一個Activity例項。這個Intent告訴Activity去啟動,並且傳遞了一些必要資料給它。在Activity結束時,如果想要從這個結束的Activity接收資料,可以使用startActivityForResult()啟動,這樣在你的Activity的
onActivityResult()
回撥就會接收到單獨的結果Intent。 - 啟動Service:Service沒有使用者介面,它的職責就是在後臺執行操作。以
Intent
為引數呼叫startService()
啟動一個Activity例項。這個Intent告訴Service去啟動,並且傳遞了一些必要資料給它。如果Service被設計成C/S結構的Server,你可以在其它元件中以Intent為引數呼叫bindService()繫結這個Service。
- 傳送廣播:一個廣播訊息是可以被任何app接收的。系統為各種系統事件傳送廣播,你也可以傳送廣播(
sendBroadcast()
,sendOrderedBroadcast()
, orsendStickyBroadcast()
)。
上述這些Intent傳遞,不會有重疊。廣播Intent僅被傳遞給Receiver,永遠不會給Activity或者Service;一個傳送給Activity的Intent是隻會被傳遞給Activity,永遠不會給一個Service或Receiver;如此類推。
Intent型別(Intent Types)
Intent有兩種型別:
- 顯式Intent:使用全類名啟動一個元件。顯示Intent啟動元件是在你自己的app當中的,因為需要知道一個元件的類名。
- 隱式Intent:不實用類名,而是通過action去啟動。隱式Intent啟動的元件允許來自於另一個app。
顯式Intent啟動,Android系統可以通過這個Intent物件立即啟動元件。
隱式Intent啟動,Android系統會將Intent的內容與裝置所有app的manifest檔案中的Intent過濾器比較,找出最合適的元件去啟動。如果Intent和Intent過濾器匹配,系統就會啟動元件並且傳遞Intent物件。如果有多個Intent過濾器匹配,系統會顯示一個對話方塊,供使用者選擇使用哪一個app。(注,Intetn過濾器是manifest中的一個符號,指明一個元件可以接收什麼樣的Intent。)
上圖為隱式Intent啟動Activity的過程。【1】Activity A通過action建立一個Intent,讓後以這個Intent為引數呼叫startActivity()。【2】Android系統會隱式Intent,搜尋匹配所有app的Intent過濾。【3】系統匹配到Activity B,呼叫它的onCreate()方法並且傳遞Intent。
警告:為了確保app的安全性,通常使用顯式Intent啟動Service,並且不給Service宣告Intetn過濾器。使用隱式Intent啟動Service是危險的,因為你不可能確定多少個Service會響應這個Intetn,並且使用者看不到哪個Service啟動了。
建立Intent(Building an Intent)
Intent的主要資訊如下:
Component name
啟動的元件名稱。
對於隱式啟動來說,Component name是可選的。但是對於顯示啟動來說,Component name是必須的資訊。沒有Component name資訊的Intent就是一個隱式的Intent,系統會基於Intent的其它資訊(比如action、data、category)決定哪個元件來接收Intent。
Action
執行通用操作的字串。
系統框架提供了許多action常量,下標列出部分內容:
常量 | 目標元件 | Action |
ACTION_CALL | Activity | 打電話 |
ACTION_SCREEN_ON | BroadcastReceiver | 螢幕開啟 |
ACTION_TIMEZONE_CHANGED | BroadcastReceiver | 時區變化 |
自定義action,應該儘量使用包名作為字首。比如:
1 static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
Data
被執行資料的URI和它的MIME型別。通常,不同的action會伴隨不同的資料型別。例如, 如果action為ACTION_EDIT, 那麼Data將包含待編輯的資料URI. 如果action為ACTION_CALL, Data將為tel:電話號碼的URI. 如果action為ACTION_VIEW, 則Data為http:網路地址的URI.
當建立一個Intent時,為資料指定一個MIME型別作為URI的補充,是非常必要的。比如,一個activity可以顯示圖片但是不能播放音訊(儘管圖片和音訊的URI是非常相似的)。因此,為資料指定一個MIME型別可以幫助Android系統找到最佳的元件接收Intent。
然而,MIME型別有時候可以通過特別的URI推測出來。比如content:
URI,它表明資料位於裝置上面,並且資料是被ContentProvider控制的,這就使的資料的MIME型別對系統來說是可見的。
警告:如果想要設定URI和MIME型別,應該呼叫setDataAndType()
;而不是同時呼叫setData()和setType(),因為它們會使彼此的值無效。
Category
一個附加資訊的的字串,包含了關於可以處理該Intent的元件種類資訊。一個Intent可以有多個Category,但是大多數Intent需要Category。下面是一些公共Category資訊:
常量 | 含義 |
CATEGORY_BROWSABLE | 目標activity可以被瀏覽器安全的啟動,用來顯示連結應用的資料——比如,一張圖片或者一封郵件 |
CATEGORY_GADGET | 這個activity可以被嵌入到另一個activity中 |
CATEGORY_HOME | 這個activity電視home介面,即裝置開啟或者按Home鍵看到的第一個頁面 |
CATEGORY_LAUNCHER | 這個activity可以作為task的初始activity,並且是被列應用程式啟動器中 |
CATEGORY_PREFERENCE | 目標activity是一個選項皮膚 |
上面的內容(component name, action, data, and category)描述了Intent的典型特徵。通過讀取這些內容,Android系統可以決定哪個元件可以被啟動。
然而,Intent還可以攜帶一些額外資訊,這些額外資訊不會影響系統選取元件,這些額外資訊就是Extras和Flags。
Extras
Key-value形式的額外資訊。
Intent類定義了許多的EXTRA_*
常量的標準資料型別。如果要自定義extra keys,應該儘量使用包名作為字首:
1 static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Flags
flag被定義在Intent類中,它作為Intent的metadata(描述資料的資料)。flag可以告訴Android系統如何啟動一個activity(比如,這個activity屬於哪一個task),並且在啟動後如何管理這個activity(比如,這個activity是否屬於recent activities列表)。
使用待定Intent(Using a Pending Intent)
PendingIntent是對Intent的包裝。PendingIntent的主要目的是授予外部程式使用被包裝的Intent,好像Intent在自己的程式中執行。
pending intent的主要使用場景如下:
- 使用者執行一個你的Notification相關的操作(Android系統的
NotificationManager會執行這個Intent)。
- 使用者執行一個你的App Widget相關的操作(Home screen app會執行這個Intent)。
- 未來某一個特定時刻執行(Android系統的AlarmManager會執行這個Intent)。
由於Intent被設計成只有特定型別的元件(Activity、Service和BroadcastReceiver)才能處理,因此PendingIntent的建立也必須要基於這層考慮。建立PendingIntent時,必須根據元件型別的不同,分別呼叫對應的方法建立:
PendingIntent.getActivity()
for anIntent
that starts anActivity
.PendingIntent.getService()
for anIntent
that starts aService
.PendingIntent.getBroadcast()
for aIntent
that starts anBroadcastReceiver
.
這些方法最好使用當前app的Context。更多的關於PendingIntent的使用,參考Notifications和App Widgets的Api指南。
Intent解析(Intent Resolution)
當系統收到一個隱式Intent的時候,系統會通過比較Intent和Intent比較器尋找最佳的activity,系統基於以下三個方面來比較:
- action
- data(URI和資料型別——MIME)
- category
Action test
一個Intent過濾器可以宣告零個或多個<action>
元素。比如:
1 <intent-filter> 2 <action android:name="android.intent.action.EDIT" /> 3 <action android:name="android.intent.action.VIEW" /> 4 ... 5 </intent-filter>