Intent就是一個激活組件的消息對象,用於組件之間的通訊。須要注意的是,能被Intent激活通訊的組件只有三類:Activity、Service和BroadcastReceiver。對應這三類組件,
Intent
有下面三種使用場景:html
Intent
爲參數調用startActivity()啓動一個Activity實例。這個Intent告訴Activity去啓動,而且傳遞了一些必要數據給它。在Activity結束時,若是想要從這個結束的Activity接收數據,可使用startActivityForResult()啓動,這樣在你的Activity的 onActivityResult()
回調就會接收到單獨的結果Intent。
Intent
爲參數調用startService()
啓動一個Activity實例。這個Intent告訴Service去啓動,而且傳遞了一些必要數據給它。若是Service被設計成C/S結構的Server,你能夠在其它組件中以Intent爲參數調用bindService()綁定這個Service。
sendBroadcast()
, sendOrderedBroadcast()
, or sendStickyBroadcast()
)。上述這些Intent傳遞,不會有重疊。廣播Intent僅被傳遞給Receiver,永遠不會給Activity或者Service;一個傳送給Activity的Intent是隻會被傳遞給Activity,永遠不會給一個Service或Receiver;如此類推。java
Intent有兩種類型:android
顯式Intent啓動,Android系統能夠經過這個Intent對象當即啓動組件。web
隱式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的主要信息以下:app
啓動的組件名稱。框架
對於隱式啓動來講,Component name是可選的。可是對於顯示啓動來講,Component name是必須的信息。沒有Component name信息的Intent就是一個隱式的Intent,系統會基於Intent的其它信息(好比action、data、category)決定哪一個組件來接收Intent。ide
執行通用操做的字符串。
系統框架提供了許多action常量,下標列出部份內容:
常量 | 目標組件 | Action |
ACTION_CALL | Activity | 打電話 |
ACTION_SCREEN_ON | BroadcastReceiver | 屏幕開啓 |
ACTION_TIMEZONE_CHANGED | BroadcastReceiver | 時區變化 |
自定義action,應該儘可能使用包名做爲前綴。好比:
1 static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
被執行數據的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(),由於它們會使彼此的值無效。
一個附加信息的的字符串,包含了關於能夠處理該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。
Key-value形式的額外信息。
Intent類定義了許多的EXTRA_*
常量的標準數據類型。若是要自定義extra keys,應該儘可能使用包名做爲前綴:
1 static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
flag被定義在Intent類中,它做爲Intent的metadata(描述數據的數據)。flag能夠告訴Android系統如何啓動一個activity(好比,這個activity屬於哪個task),而且在啓動後如何管理這個activity(好比,這個activity是否屬於recent activities列表)。
PendingIntent是對Intent的包裝。PendingIntent的主要目的是授予外部程序使用被包裝的Intent,好像Intent在本身的進程中執行。
pending intent的主要使用場景以下:
NotificationManager會執行這個Intent)。
因爲Intent被設計成只有特定類型的組件(Activity、Service和BroadcastReceiver)才能處理,所以PendingIntent的建立也必需要基於這層考慮。建立PendingIntent時,必須根據組件類型的不一樣,分別調用對應的方法建立:
PendingIntent.getActivity()
for an Intent
that starts an Activity
.PendingIntent.getService()
for an Intent
that starts a Service
.PendingIntent.getBroadcast()
for a Intent
that starts an BroadcastReceiver
.這些方法最好使用當前app的Context。更多的關於PendingIntent的使用,參考Notifications和App Widgets的Api指南。
當系統收到一個隱式Intent的時候,系統會經過比較Intent和Intent比較器尋找最佳的activity,系統基於如下三個方面來比較:
一個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>