Android——Intent和Intent過濾器

Intent就是一個激活組件的消息對象,用於組件之間的通訊。須要注意的是,能被Intent激活通訊的組件只有三類:Activity、Service和BroadcastReceiver。對應這三類組件,Intent有下面三種使用場景:html

  • 啓動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(), or sendStickyBroadcast())。

上述這些Intent傳遞,不會有重疊。廣播Intent僅被傳遞給Receiver,永遠不會給Activity或者Service;一個傳送給Activity的Intent是隻會被傳遞給Activity,永遠不會給一個Service或Receiver;如此類推。java

Intent類型(Intent Types)


Intent有兩種類型:android

  • 顯式Intent:使用全類名啓動一個組件。顯示Intent啓動組件是在你本身的app當中的,由於須要知道一個組件的類名。
  • 隱式Intent:不實用類名,而是經過action去啓動。隱式Intent啓動的組件容許來自於另外一個app。

顯式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(Building an Intent)


Intent的主要信息以下:app

Component name

啓動的組件名稱。框架

對於隱式啓動來講,Component name是可選的。可是對於顯示啓動來講,Component name是必須的信息。沒有Component name信息的Intent就是一個隱式的Intent,系統會基於Intent的其它信息(好比action、data、category)決定哪一個組件來接收Intent。ide

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時,必須根據組件類型的不一樣,分別調用對應的方法建立:

這些方法最好使用當前app的Context。更多的關於PendingIntent的使用,參考NotificationsApp 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>
相關文章
相關標籤/搜索