intent

intent

解決安卓應用的各項組件之間的通訊
Intent(意圖)主要是解決Android應用的各項組件之間的通訊。Intent負責對應用中一次操作的動作、動作涉及數據、附加數據進行描述,Android則根據此Intent的描述,負責找到對應的組件,将Intent傳遞給調用的組件,并完成組件的調用。[1]因此,Intent在這裡起着一個媒體中介的作用,專門提供組件互相調用的相關信息,實現調用者與被調用者之間的解耦。例如,在一個聯系人維護的應用中,當我們在一個聯系人列表屏幕(假設對應的Activity為listActivity)上,點擊某個聯系人後,希望能夠跳出此聯系人的詳細信息屏幕(假設對應的Activity為detailActivity)為了實現這個目的,listActivity需要構造一個Intent,這個Intent用于告訴系統,我們要做“查看”動作,此動作對應的查看對象是“某聯系人”,然後調用startActivity(Intentintent),将構造的Intent傳入,系統會根據此Intent中的描述,到ManiFest中找到滿足此Intent要求的Activity,系統會調用找到的Activity,即為detailActivity,最終傳入Intent,detailActivity則會根據此Intent中的描述,執行相應的操作。
    中文名:意圖 外文名:intent 定義: 作用:解決Android應用各項組件的通訊 性質:媒體中介 提供信息:組件互相調用的相關信息 實現目的:調用者與被調用者之間的解耦

抽象描述要描述什麼

在Android參考文檔中,對Intent的定義是執行某操作的一個抽象描述(确實很抽象)。我們先來看看這裡的抽象描述,到底描述了什麼。

首先,是要執行的動作(action)的一個簡要描述,如VIEW_ACTION(查看)、EDIT_ACTION(修改)等,Android為我們定義了一套标準動作:

MAIN_ACTION

VIEW_ACTION

EDIT_ACTION

PICK_ACTION

GET_CONTENT_ACTION

DIAL_ACTION

CALL_ACTION

SENDTO_ACTION

ANSWER_ACTION

INSERT_ACTION

DELETE_ACTION

RUN_ACTION

LOGIN_ACTION

CLEAR_CREDENTIALS_ACTION

SYNC_ACTION

PICK_ACTIVITY_ACTION

WEB_SEARCH_ACTION

此外,我們還可以根據應用的需要,定義我們自己的動作,并可定義相應的Activity來處理我們的自定義動作。

其次,是執行動作要操作的數據(data),Android中采用指向數據的一個URI來表示,如在聯系人應用中,一個指向某聯系人的URI可能為:content://contacts/1。

這種URI表示,通過ContentURI這個類來描述,具體可以參考android.net.ContentURI類的文檔。

以聯系人應用為例,以下是一些action/data對,及其它們要表達的意圖:

VIEW_ACTION content://contacts/1--顯示标識符為"1"的聯系人的詳細信息

EDIT_ACTION content://contacts/1--編輯标識符為"1"的聯系人的詳細信息

VIEW_ACTION content://contacts/--顯示所有聯系人的列表

PICK_ACTION content://contacts/--顯示所有聯系人的列表,并且允許用戶在列表中選擇一個聯系人,然後把這個聯系人返回給父activity。例如:電子郵件客戶端可以使用這個Intent,要求用戶在聯系人列表中選擇一個聯系人

另外,除了action和data這兩個重要屬性外,還有一些附加屬性:

category(類别),被執行動作的附加信息。例如LAUNCHER_CATEGORY表示Intent的接受者應該在Launcher中作為頂級應用出現;而ALTERNATIVE_CATEGORY表示當前的Intent是一系列的可選動作中的一個,這些動作可以在同一塊數據上執行。

type(數據類型),顯式指定Intent的數據類型(MIME)。一般Intent的數據類型能夠根據數據本身進行判定,但是通過設置這個屬性,可以強制采用顯式指定的類型而不再進行推導。

component(組件),指定Intent的的目标組件的類名稱。通常Android會根據Intent中包含的其它屬性的信息,比如action、data/type、category進行查找,最終找到一個與之匹配的目标組件。但是,如果component這個屬性有指定的話,将直接使用它指定的組件,而不再執行上述查找過程。指定了這個屬性以後,Intent的其它所有屬性都是可選的。

extras(附加信息),是其它所有附加信息的集合。使用extras可以為組件提供擴展信息,比如,如果要執行“發送電子郵件”這個動作,可以将電子郵件的标題、正文等保存在extras裡,傳給電子郵件發送組件。

總之,action、data/type、category和extras一起形成了一種語言。

這種語言使系統能夠理解諸如“查看某聯系人的詳細信息”之類的短語。随着應用不斷的加入到系統中,它們可以添加新的action、 data/type、category來擴展這種語言。應用也可以提供自己的Activity來處理已經存在的這樣的“短語”,從而改變這些“短語”的行為。

解析方式

在應用中,我們可以以兩種形式來使用Intent:

直接Intent:指定了component屬性的Intent(調用setComponent(ComponentName)或者setClass(Context,Class)來指定)。通過指定具體的組件類,通知應用啟動對應的組件。

間接Intent:沒有指定comonent屬性的Intent。這些Intent需要包含足夠的信息,這樣系統才能根據這些信息,在在所有的可用組件中,确定滿足此Intent的組件。

對于直接Intent,Android不需要去做解析,因為目标組件已經很明确,Android需要解析的是那些間接Intent,通過解析,将Intent映射給可以處理此Intent的Activity、IntentReceiver或Service。

Intent解析機制主要是通過查找已注冊在AndroidManifest.xml中的所有IntentFilter及其中定義的Intent,最終找到匹配的Intent。在這個解析過程中,Android是通過Intent的action、type、category這三個屬性來進行判斷的,判斷方法如下:

如果Intent指明定了action,則目标組件的IntentFilter的action列表中就必須包含有這個action,否則不能匹配;如果Intent沒有提供type,系統将從data中得到數據類型。和action一樣,目标組件的數據類型列表中必須包含Intent的數據類型,否則不能匹配。

如果Intent中的數據不是content:類型的URI,而且Intent也沒有明确指定它的type,将根據Intent中數據的scheme(比如http:或者mailto:) 進行匹配。同上,Intent的scheme必須出現在目标組件的scheme列表中。

如果Intent指定了一個或多個category,這些類别必須全部出現在組建的類别列表中。比如Intent中包含了兩個類别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标組件必須至少包含這兩個類别。

顯式調用和隐式調用

顯式Intent直接用組件的名稱定義目标組件,這種方式很直接。但是由于開發人員往往并不清楚别的應用程序的組件名稱,因此,顯式Intent更多用于在應用程序内部傳遞消息。比如在某應用程序内,一個Activity啟動一個Service。

隐式Intent恰恰相反,它不會用組件名稱定義需要激活的目标組件,它更廣泛地用于在不同應用程序之間傳遞消息。

在顯式Intent消息中,決定目标組件的唯一要素就是組件名稱,因此,如果你的Intent中已經明确定義了目标組件的名稱,那麼你就完全不用再定義其他Intent内容。

而對于隐式Intent則不同,由于沒有明确的目标組件名稱,所以必須由Android系統幫助應用程序尋找與Intent請求意圖最匹配的組件。

(Intent定義:Intent是一種在不同組件之間傳遞的請求消息,是應用程序發出的請求和意圖。作為一個完整的消息傳遞機制,Intent不僅需要發送端,還需要接收端。

顯式Intent定義:對于明确指出了目标組件名稱的Intent,我們稱之為顯式Intent。

隐式Intent定義:對于沒有明确指出目标組件名稱的Intent,則稱之為隐式Intent。

說明:Android系統使用IntentFilter來尋找與隐式Intent相關的對象。

顯式Intent直接用組件的名稱定義目标組件,這種方式很直接。但是由于開發人員往往并不清楚别的應用程序的組件名稱,因此,顯式Intent更多用于在應用程序内部傳遞消息。比如在某應用程序内,一個Activity啟動一個Service。

隐式Intent恰恰相反,它不會用組件名稱定義需要激活的目标組件,它更廣泛地用于在不同應用程序之間傳遞消息。

在顯式Intent消息中,決定目标組件的唯一要素就是組件名稱,因此,如果你的Intent中已經明确定義了目标組件的名稱,那麼你就完全不用再定義其他Intent内容。

而對于隐式Intent則不同,由于沒有明确的目标組件名稱,所以必須由Android系統幫助應用程序尋找與Intent請求意圖最匹配的組件。

Android系統尋找與Intent請求意圖最匹配的組件具體的選擇方法是:Android将Intent的請求内容和一個叫做IntentFilter的過濾器比較,IntentFilter中包含系統中所有可能的待選組件。

如果IntentFilter中某一組件匹配隐式Intent請求的内容,那麼Android就選擇該組件作為該隐式Intent的目标組件。

Android如何知道應用程序能夠處理某種類型的Intent請求呢?這需要應用程序在Android-Manifest.xml中聲明自己所含組件的過濾器(即可以匹配哪些Intent請求)。

一個沒有聲明Intent-Filter的組件隻能響應指明自己名字的顯式Intent請求,而無法響應隐式Intent請求。

而一個聲明了IntentFilter的組件既可以響應顯式Intent請求,也可以響應隐式Intent請求。在通過和IntentFilter比較來解析隐式Intent請求時,Android将以下三個因素作為選擇的參考标準:

Action

Data

Category

而Extra和Flag在解析收到Intent時是并不起作用的。

相關詞條

相關搜索

其它詞條