Android 中各個組件主要是通過Intent來通訊。
Intent負責對應用中一次操作的動作、動作涉及資料、附加資料進行描述,Android則根據此Intent的描述,負責找到對應的組件,將 Intent傳遞給調用的組件,並完成組件的調用。
因此,Intent在這裡起著一個媒體中介的作用,專門提供組件互相調用的相關資訊,實現調用者與被調用者之間的解耦。
Intent 作用:
An intent is an abstract description of an operation to be performed. It can be used with startActivity to launch an Activity, broadcastIntent to send it to any interested BroadcastReceiver components, and startService(Intent) or bindService(Intent, ServiceConnection, int) to communicate with a background Service.
An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed. The primary pieces of information in an intent are:
1.startActivity
2. broadcastIntent
3.startService()
4.bindService()
組件之間通訊和進程間通訊,減低耦合性。
Intent 各個屬性1.action (動作) 是要執行的動作(action)的一個簡要描述,如VIEW_ACTION(查看)、EDIT_ACTION(修改)等,Android為我們定義了一套標準動作。The general action to be performed
2.data是執行動作要操作的資料(data),Android中採用指向資料的一個URI來表示 The data to operate on
3.category(類別),被執行動作的附加資訊。例如 LAUNCHER_CATEGORY 表示Intent 的接受者應該在Launcher中作為頂級應用出現;而ALTERNATIVE_CATEGORY表示當前的Intent被加進ALTERNATIVE intent列表裡面,使用者可以啟動,it should be included in a list of alternative actions the user can perform on a piece of data.
4.type(資料類型),顯式指定Intent的資料類型(MIME)。一般Intent的資料類型能夠根據資料本身進行判定,但是通過設定這個屬性,可以強制採用顯式指定的類型而不再進行推導。
5.component(組件),指定Intent的的目標組件的類名稱。通常 Android會根據Intent 中包含的其它屬性的資訊,比如action、data/type、category進行尋找,最終找到一個與之匹配的目標組件。但是,如果 component這個屬性有指定的話,將直接使用它指定的組件,而不再執行上述尋找過程。指定了這個屬性以後,Intent的其它所有屬性都是可選的。
6.extras(附加資訊),是其它所有附加資訊的集合。使用extras可以為組件提供擴充資訊,比如,如果要執行“寄送電子郵件”這個動作,可以將電子郵件的標題、本文等儲存在extras裡,傳給電子郵件發送組件。
Android如何解析Intent
在應用中,我們可以以兩種形式來使用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這三個屬性來進行判斷的,判斷方法如下:
1.如果Intent指明定了action,則目標組件的IntentFilter的action列表中就必須包含有這個action,否則不能匹配;
2.如果Intent沒有提供type,系統將從data中得到資料類型。和action一樣,如果Intent指明定了type,目標組件的資料類型列表中必須包含Intent的資料類型,否則不能匹配。
3.如果Intent中的資料不是content: 類型的URI,而且Intent也沒有明確指定它的type,將根據Intent中資料的scheme (比如 http: 或者mailto: ) 進行匹配。同上,Intent 的scheme必須出現在目標組件的scheme列表中。
4.如果Intent指定了一個或多個category,這些類別必須全部出現在組件的類別列表中。比如Intent中包含了兩個類別:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目標組件必須至少包含這兩個類別。Activities will very often need to support the CATEGORY_DEFAULT so that they can be found by Context.startActivity().
5.如果category 指定了ALTERNATIVE and SELECTED_ALTERNATIVE.則可以通過queryIntentActivityOptions(ComponentName, Intent[], Intent, int),查詢Activity的action,addIntentOptions(int, int, int, ComponentName, Intent[], Intent, int, MenuItem[])增加action等資訊。
Intent 的研究離不開IntentFilter.
總結:利用Intent所實現的軟體複用的粒度是Activity/Service,耦合也更為鬆散。