【Android】Intent理解

Android基本的設計理念是鼓勵減少組件間的耦合,因此Android提供了Intent (意圖) ,Intent提供了一種通用的消息系統,它允許在你的應用程序與其它的應用程序間傳遞Intent來執行動作和產生事件。使用Intent可以激活Android應用的三個核心組件:活動(Activity)、服務(Service)和廣播接收器(BroadcastReceiver)。 

    Intent可以劃分成顯式意圖和隱式意圖。

    顯式意圖:調用Intent.setComponent()或Intent.setClass()方法明確指定了組件名的Intent爲顯式意圖,顯式意圖明確指定了Intent應該傳遞給哪個組件。

    隱式意圖:沒有明確指定組件名的Intent爲隱式意圖。 Android系統會根據隱式意圖中設置的動作(action)、類別(category)、數據(URI和數據類型)找到最合適的組件來處理這個意圖。


意圖啓動

啓動不返回結果的意圖,使用startActivity(intent)。

啓動返回結果的意圖,使用startActivityForResult(intent, SHOW_SUBACTIVITY),SHOW_SUBACTIVITY是請求碼,用來在接收回調結果的onActivityResult(int requestCode, int resultCode, Intent data)方法中區分打開的子activity的回調。

若要傳遞責任給次最佳匹配的組件,則在onCreate中獲取intent後使用startNextMatchingActivity(intent)。

 

意圖過濾器

如果意圖過濾器包含了指定的動作,或者沒有指定動作,那麼就認爲動作匹配。

意圖過濾器必須包含待解析的意圖中的所有category,沒有指定category的意圖過濾器只能和沒有任何category的意圖相匹配。需要注意的是,Android把所有傳給startActivity()的隱式意圖當作他們包含至少一個類別:"android.intent.category.DEFAULT" (CATEGORY_DEFAULT常量)。

意圖的數據URI的每一個部分都和意圖過濾器的data標籤進行比較,沒有指定數據值的意圖過濾器將會和所有的意圖數據值匹配。


Intent類中的靜態字符串常量

action:

ACTION_ANSWER 打開一個處理來電的活動

ACTION_CALL 打開一個電話撥號程序,並立即使用意圖URI所提供的號碼撥打一個電話

ACTION_DELETE 啓動一個活動,允許刪除意圖的URI中指定的數據

ACTION_DIAL 打開一個撥號程序,撥打意圖URI所提供的號碼

ACTION_EDIT 請求可以編輯指定的意圖URI中的數據的活動

ACTION_INSERT 打開一個能在意圖URI指定的光標出插入新條目的活動

ACTION_PICK 啓動一個子活動,它可以讓你從意圖URI指定的內容提供器中選擇一個條目

ACTION_SEARCH 啓動用於執行搜索的活動

ACTION_SENDTO 啓動一個活動來向意圖URI所指定的聯繫人發送一條消息

ACTION_SEND 啓動一個活動,發送意圖中指定的數據

ACTION_VIEW 通用動作,根據所提供的數據的URI模式來處理視圖請求

ACTION_WEB_SEARCH 根據意圖URI提供的文本執行Web搜索

category:

ALTERNATIVE 把動作指定爲在特定數據類型上執行的默認動作的可選項

SELECTED_ALERNATIVE 使用動作幫助填充上下文菜單

BROWSABLE 瀏覽器內部可用的動作

DEFAULT 使一個組件成爲意圖過濾器內指定的數據類型的默認動作

GADGET 活動可以嵌入到另一個活動中執行

HOME 不指定action時,意圖則作爲本地主屏幕的可選項

LAUNCHER 出現在應用程序的啓動器中


<intent-filter>

<action android:name="android.intent.action.CALL" />

<category android:name="android.intent.category.DEFAULT" />

<data android:scheme="tel" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.CALL" />

<category android:name="android.intent.category.DEFAULT" />

<data android:mimeType="vnd.android.cursor.item/phone" />

</intent-filter>


    對於隱式意圖,Android是怎樣尋找到這個最合適的組件呢?記的前面我們在定義活動時,指定了一個intent-filter,Intent Filter(意圖過濾器)其實就是用來匹配隱式Intent的,當一個意圖對象被一個意圖過濾器進行匹配測試時,只有三個方面會被參考到:動作、數據(URI以及數據類型)和類別。

動作測試(Action test)

 一個意圖對象只能指定一個動作名稱,而一個過濾器可能列舉多個動作名稱。如果意圖對象或過濾器沒有指定任何動作,結果將如下:

• 如果過濾器沒有指定任何動作,那麼將阻塞所有的意圖,因此所有的意圖都會測試失敗。沒有意圖能夠通過這個過濾器。

• 另一方面,只要過濾器包含至少一個動作,一個沒有指定動作的意圖對象自動通過這個測試

類別測試(Category test)

對於一個能夠通過類別匹配測試的意圖,意圖對象中的類別必須匹配過濾器中的類別。這個過濾器可以列舉另外的類別,但它不能遺漏在這個意圖中的任何類別。

原則上一個沒有類別的意圖對象應該總能夠通過匹配測試,而不管過濾器裏有什麼。大部分情況下這個是對的。但有一個例外,Android把所有傳給startActivity()的隱式意圖當作他們包含至少一個類別:"android.intent.category.DEFAULT" (CATEGORY_DEFAULT常量)。 因此,想要接收隱式意圖的活動必須在它們的意圖過濾器中包含"android.intent.category.DEFAULT"。(帶"android.intent.action.MAIN"和"android.intent.category.LAUNCHER"設置的過濾器是例外)

數據測試(Data test)

當一個意圖對象中的URI被用來和一個過濾器中的URI比較時,比較的是URI的各個組成部分。例如,如果過濾器僅指定了一個scheme,所有該scheme的URIs都能夠和這個過濾器相匹配;如果過濾器指定了一個scheme、主機名但沒有路經部分,所有具有相同scheme和主機名的URIs都可以和這個過濾器相匹配,而不管它們的路經;如果過濾器指定了一個scheme、主機名和路經,只有具有相同scheme、主機名和路經的URIs纔可以和這個過濾器相匹配。當然,一個過濾器中的路徑規格可以包含通配符,這樣只需要部分匹配即可。

數據測試同時比較意圖對象和過濾器中指定的URI和數據類型。規則如下:

a. 一個既不包含URI也不包含數據類型的意圖對象僅在過濾器也同樣沒有指定任何URIs和數據類型的情況下才能通過測試。

b. 一個包含URI但沒有數據類型的意圖對象僅在它的URI和一個同樣沒有指定數據類型的過濾器裏的URI匹配時才能通過測試。這通常發生在類似於mailto:和tel:這樣的URIs上:它們並不引用實際數據。

c. 一個包含數據類型但不包含URI的意圖對象僅在這個過濾器列舉了同樣的數據類型而且也沒有指定一個URI的情況下才能通過測試。

d. 一個同時包含URI和數據類型(或者可從URI推斷出數據類型)的意圖對象可以通過測試,如果它的類型和過濾器中列舉的類型相匹配的話。如果它的URI和這個過濾器中的一個URI相匹配或者它有一個內容content:或者文件file: URI而且這個過濾器沒有指定一個URI,那麼它也能通過測試。換句話說,一個組件被假定爲支持content:和file: 數據如果它的過濾器僅列舉了一個數據類型。
發佈了18 篇原創文章 · 獲贊 35 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章