Intent 是一個可以從App組件(Activity,Service,ContentProvider,BroadcastReceiver)請求動作(action)的消息對象,實現從一個組件跳轉到另一個組件的功能,通過閱讀文檔,可以瞭解到:
Intent的三種基本使用場景:
- 啓動一個Activity
- 啓動一個Service
- 發送一個Broadcast
Intent的種類:
顯示Intent,啓動指定名字(組件的class類名)的組件
隱式Intent,(設備上的任何App通過過濾匹配可以執行這個Action)沒有指定名字,通過申明動作(action)執行,組件接收到這個動作便會執行相關代碼,允許其他App中的組件處理這個action,隱式的Intent通過Intent Filter進行過濾
注意,如果設備上沒有App可以處理你指定的Intent,調用時你的App將會崩潰,爲了防止這種事發生,最好在startActivity()之前調用resolveActivity()檢測設備上是否有能執行此Intent的App,返回結果不會空則說明有,否則沒有能執行此Intent的App,這時你就需要考慮使用其他方式處理你的Intent了
通常啓動Service的Intent爲顯示的,這樣子才安全,因爲從Android 5.0之後,通過隱式的Intent調用bindService(),系統將會拋出異常
發送一個Intent時的組成:
需要啓動的組件名字(className,通過如下方法設置:setCompontent(),setClass(),setClassName(),或者在Intent的構造方法中定義)隱式的Intent不需要申明組件名
動作(Action,用於Intent Filter篩選的條件)通常系統有一些特定的Action可供調用,如ACTION_VIEW(啓動一個查看內容的App),ACTION_SEND(啓動一個可以發送數據App),創建自定義Action時,一定要記得加上包名,如:static final String ACTION_EXAMPLE=”com.example.action.EXAMPLE”
數據和類型(data,type)Data是指定Action處理的對象,通常是以URi形式存在,Type用以指出Data的類型,例如一個Action爲ACTION_EDIT,則它的Data應該是某個可編輯的文本的Uri,而它的Type應該指明這個文本的類型
分類(Category):包含了需要處理Intent的組件的分類信息,(即,區分哪種類型的組件可以處理這個Intent) 在一個測試隱式Intent的例子中,因爲接收端App的Activity中Intent Filter沒有設置這個屬性,導致始終不能跳轉到接收端App中的Activity。 下面將會給出原因
附件(Extras):用於傳遞鍵值對數據
標誌位(Flags):用來通知Android System如何運行一個activity和運行以後如何處理
接收一個Intent時的組成:(通過定義Intent Filter過濾得到想要的Intent,通常在清單文件(AndroidManifest.xml)中使用< intent-filter >標籤來過濾。)
< action >:申明可接受的動作名,用於匹配篩選出相同名的動作,其值必須爲字符串而不能是常量類型,一個組件可以過濾多個Action
< data >:申明可以接收的數據類型,可以使用多組屬性值進行多種數據類型匹配篩選
< category >:申明可以接收的Intent類型(注意,爲了能接收到隱式的Intent,必須在Intent Filter中添加默認類型,否則系統檢測不到Intent匹配的Activity
< category android:name="android.intent.category.DEFAULT"/>
)
以上,一條基本的過濾器就申明完成
Intent Filter的過濾原則:(通常,在< intent-filter >節點下可以有多個< action >, < category >或 < data >節點用來對Intent進行匹配過濾篩選,其過濾篩選原則如下)
< action >:過濾器中可以列出多個動作,匹配時Intent中的action值只要有一個配對了,則通過
< category >:過濾器中可以列出多個分類,匹配時Intent中的category必須每一個都對應才能通過,通過startActivity()啓動的隱式Intent會有個默認的category:CATEGORY_DEFAULT常量,所以在< category >標籤中必須要有個默認的值才能匹配到隱式Intent,這也就解釋了上文中的那個測試。
通過設置該< intent-filter>對應的組件中的 exported屬性爲false,可以讓你的組件只接受當前App內的Intent調用,也就是其他App通過隱式Intent不能調用你的組件
待召意圖(PendingIntent)意爲即將發生的意圖,是Intent的一種包裝,首要目的是授予另一個程序權限,任由它像你的程序一樣來執行相應的操作,其主要使用場景爲:
申明一個將要執行的Intent,當用戶點擊通知時執行(因爲不知道什麼時候會有通知來)
申明一個將要執行的Intent,當用戶點擊桌面小插件的時候執行
- 申明一個將要執行的Intent,在指定的一個將來時間執行(也就是定時執行)
Intent和PendingIntent的主要區別,當前activity並不能馬上啓動它所包含的intent,而是在外部執行 pendingintent時,調用intent的。正由於pendingintent中 保存有當前App的Context,使它賦予外部App一種能力,使得外部App可以如同當前App一樣的執行pendingintent裏的 Intent, 就算在執行時當前App已經不存在了,也能通過存在pendingintent裏的Context照樣執行Intent,因此具有很大的靈活性
Common Intent
之前說過,Intent既可以啓動當前應用程序中的Activity,也可以啓動設備上任意符合過濾條件的Activity,後者稱爲隱式Intent(implicit Intent),通常,使用隱式Intent是爲了啓動一個公用的Activity來完成當前應用程序不具備的功能,比如拍照,打開相冊,播放音樂或視頻,設備上已經有了具備這些功能的應用,通過隱式Intent就可以直接使用,並將結果返回給當前應用程序,因此,可以稱這類Intent爲Common Intent(公共Intent),通過閱讀這節內容將會瞭解到如何調用一些系統應用程序,具體使用與參數配置,可以參考官方文檔:Common Intents
注意!在調用系統應用時,首先要確保申請了必須的權限