【Android開發精要筆記】Android的Intent機制

Android的Intent機制

Intent對象的做用和構成

android意圖機制最核心的設計思想,就是引入了組件管理服務做爲鏈接組件的管理者。 該服務的做用:android

  • 經過組件的配置信息瞭解系統中每一個組件的類別和功能
  • 幫助調用組件尋找符合其需求的實現組件,將調用者與實如今完全解耦

在整個意圖機制下,有三方角色參與組件間的鏈接和通訊git

【調用組件】鏈接請求的發起者,它指望尋找其餘組件來幫助完成所需的功能。經過調用startActivity和bindService等函數發起對目標組件的鏈接請求github

【實現組件】響應調用者請求完成所需任務的組件,每一個組件均可以做爲調用者請求第三方幫助,也均可以扮演實現着去完成對應的請求。對於實現組件而已,不須要關注其調用者是誰,只需依照請求者發送的Intent對象去執行相關功能便可算法

【組件管理服務】在調用組件與實現組件的鏈接過程當中,組件管理服務扮演了調度者的角色。從調用組件中接收到Intent對象,而後將該對象與應用管理服務收集到的組件Intent Filter對象進行比較,從中選擇出符合調用組件需求的實現組件,最後構造並調用實現組件對象,組件管理服務是一個系統服務,運行在系統核心進程的獨立線程中,經過進程間通訊機制,與各組件進行交互緩存

Intent對象的做用

Intent對象是組件間通訊信息的載體。它封裝了調用組件提供的指令和數據,經過組件管理服務序列化傳遞給實現組件,實現組件能夠利用這些信息完成所需功能。 Intent對象定義了組件間鏈接協議。每一個Intent對象都包含若干個數據項,每一個數據項都有其內涵,調用者組件根據這些規範構造Intent對象描述其需求;實現組件根據這些規範解析Intent對象執行所需功能;而組件管理服務依照這些規範尋找與需求匹配的組件,構造鏈接ide

Intent對象的構成

Intent類的實現很是簡單,只是包含了若干個數據項函數

  • Action項 Action就是用來表達動做的。Action就是一個字符串,能夠用setAction函數爲intent對象指定一個動做,也能夠用getAction讀取Intent對象中的動做信息。
  • Data項 意願的表達,好比我吃宮保雞丁,主語「我」,在乎圖機制下對應着調用組件,謂語「吃」,用Intent的Action對象來表達,賓語"宮保雞丁"則對應着Data,setData,setDataAndType來進行設置,經過getData函數來讀取。Data數據也是用字符串進行存儲的,它的個數符合URI標準,URI具備豐富的表達能力,可以表達存儲在任何地方的數據
  • Type項 若是Data用於特指,那麼Type用於泛指,setType,setDataAndType,getType,Type是MIME格式的字符串數據,用於描述組件可以處理的請求類型,或者補充說明Data數據的類型。能夠經過通配符*來表示整個類別的信息 在Intent對象中,Data項和Type項不少時候是互斥使用的。一個Intent中,須要Data表示數據仍是用Type表示數據類型一般是和Action密切相關的。
  • Category項 category表示約束,每一個Intent對象可包含多個Categories。addCategory添加Category項,getCategories獲取該Intent對象Category項的集合。同一個Intent中的多個Category項彼此間是"與"關係。也就是說一個組件須要支持所有的Category項才能處理該請求。
  • Component項 Component指的是目標組件的類型信息,經過setComponent方法利用類名進行設定,也能夠經過setClass方法利用類型對象信息進行設置。當調用組件明確了Component信息,組件管理服務就再也不須要根據Action、Data等信息去尋找知足其需求的實現組件了。只需按照Component信息實例化對於的組件做爲功能實現者便可。
  • Extras項 Extras是Intent中數據傳輸的載體,負責將數據從調用組件傳遞到實現組件。Extras是一個Bundle對象,該對象按照鍵值對的方式存儲數據,它實現了Parcelable接口,能夠進行數據的序列化和反序列化,從而在進程中傳遞。
  • Flags項 一個整形數,由一系列的標誌位聚集而成。它對於實現組件而言徹底透明,是調用組件指定組件管理服務構造實現組件的方式,經常使用於改變實現組件的任務模型和進程模型等。被設定的Flags標誌位將會疊加生效。但須要注意的是,不少標誌位之間是相關聯邏輯關係的,有的標誌位須要同時設定,而有的標誌位直接則具備必定的互斥性。

Intent對象解析

組件管理服務負責接收和分析Intent對象。Intent對象能夠分紅兩類:精確描述的Intent(Explicit Intent)和模糊描述的Intent(Implicit Intent) 精確描述的Intent,指的是全部帶有Component信息的Intent對象。在精確描述的前提下,Intent對象只是做爲消息的載體存在 模糊描述的Intent,對基於模糊描述的Intent調用組件而言,它們不在意實現組件是誰,只要求該組件可以依照Intent對象中描述的意圖和需求完成對應的任務。 精確描述的Intent一般用於應用內部的通訊,由於調用組件和實現組件彼此瞭解,不須要動態機制,只須要最快地將消息傳遞過去就行了。 而模糊描述的Intent,則用於不一樣應用組件間的互聯互通,它的存在將請求者和實現者徹底解耦,極大地提高了系統的靈活性。優化

Intent Filter對象

與Intent類似,IntentFilter對象也包含Action、Type、Data、Category等數據項,每一個數據項的結構和含義,與Intent中的數據項也一一對應。當組件管理服務接收到調用組件發送來的基於模糊描述的Intent對象時,會與全部組件的IntentFilter信息進行匹配技術,尋找符合需求的實現組件。 每一個組件均可以有任意數量的IntentFilter,組件包含的Intent Filter對象越多,說明它能接受Intent請求的範圍越廣。而不添加任何Intent Filter對象的組件,僅能經過Intent對象精確地進行調用 組件對於的IntentFilter信息,通常經過配置文件的項進行添加,放在界面組件、服務組件或觸發器組件的配置項中。線程

意圖匹配的算法流程

Intent對象和Intent Filter對象的匹配過程,就稱爲意圖匹配算法。 設計

算法輸入的是進行比較的Intent對象和Intent Filter對象,輸出的是一個32位的整數值,用於表徵二者的匹配程度。 整個匹配算法的流程可分爲3個步驟 1. Action的比較:每一個IntentFilter對象都必須包含Action信息,若是沒有,則對任何一個Intent對象都會匹配失敗 2. Data和Type的比較:Data和Type信息是Intent Filter中最複雜的數據項,其比較算法是決定Intent與Intent Filter對象匹配程度的關鍵 3. Category的比較

匹配組件的選擇

若是有多個Intent Filter對象與調用組件發出的Intent對象都相匹配,就須要在全部符合條件的Intent Filter對象中進行篩選,選出最符合調用組件和用戶需求的實現組件,這個流程就稱爲匹配組件的選擇。 在組件選擇上,最核心的機制就是基於優先級的排序。每個Intent Filter對象都有一個優先級,從-1000到1000,值越大,優先級越高 實例例子,如攔截短信,能夠採起提高Intent Filter優先級的策略來實現:

<receiver android:name="third_parth.SmsReceiver">
        <intent-filter>
            <action android:priority="1000"
                android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
    </receiver>

在third_party.SmsReceiver這個觸發組件中,系統能夠定製策略攔截特定的短信,經過調用abortBroadcast()函數終止廣播,使其餘短信應用的Intent Filter沒法匹配短信通知

public void onReceive(Context context,Intent intent)
{
    if(IsBlockSms(intent))
        abortBroadcast();
}

意圖匹配的優化

意圖機制中,引入第三方組件管理服務,下降了調用組件和實現組件之間的耦合,提升了系統的靈活性及組件的複用性,但同時,因爲第三方服務地介入增長了組件間鏈接的成本,可能會使組件間的調用不夠流暢。所以,系統對組件的匹配和選擇過程進行了大量的優化,以提高意圖匹配和組件調用的效率。

  • 索引:此流程涉及大量的字符串比較,比較耗時。組件管理服務會經過哈希表,爲全部Intent Filter對象的Action、Type等數據項創建索引。每一個索引對應着一組Action相同,Type相同,或者其餘數據項相同的Intent Filter對象。Intent對象會先將其中的數據項與索引項進行比較,快速地選擇出可能與Intent相匹配的Intent Filter對象。
  • 緩存:將Intent和Intent Filter的匹配結果記錄下來,當再碰到相同的Intent的調用時,可直接返回上次記錄的結果,從而跳過意圖匹配的過程,加速組件的調用。服務組件,組件管理服務會在內存中經過哈希表的形式保留各個Intent對應的服務組件。

意圖機制的應用

意圖機制在界面組件中的應用

調用組件能夠經過調用startActivity和startActivityForResult等函數發起對目標界面組件的調用,選擇並構造出一個符合其需求的界面組件實例,切換至前臺與用戶進行交互。調用組件能夠在構造的Intent對象中添加一些Flags標誌位信息,用於告知組件管理服務如何去構造實現組件。當多個界面組件都能知足調用組件的需求,就須要從中選擇一個最適合的組件做爲最終的實現組件。對於界面組件的選擇,須要兼顧效率和公平性。

  • 效率:選擇過程當中儘量流暢
  • 公平性:每一個符合調用者需求的組件,都應當具備同等的權利來響應調用組件的請求。 首先,經過算法對已排序的Intent Filter進行篩選,組件管理服務會將排序後隊列中的第一個Intent Filter對象(記爲A)與第二個Intent Filter對象(記做B)進行比較,若是知足一下條件中的一個,組件管理服務就會直接選擇A對象對應的組件做爲實現組件
  • A的優先級高於B
  • A包含intent.CATEGORY_DEFAULT,而B沒有 同時,Android會將全部符合需求的組件列舉起來,讓用戶決定選擇哪一個組件來執行該操做。用戶能夠選擇該組件做爲執行相似Intent調用的默認組件 若是調用組件指望繞過默認值的約束,讓用戶根據當前場景再次作出選擇,能夠經過Intent.createChooser方法自定義組件選擇列表 activity.startActivity(Intent.createChooser(intent,R.strng.invite_friend));

意圖機制在服務組件中的應用

調用組件能夠調用Context.startService函數啓動符合需求的服務組件,也能夠經過Context.bindService函數綁定對應的服務組件。因爲服務組件是在後臺提供服務的,當出出現多個匹配項時,沒法像界面組件同樣構造交互界面讓用戶來抉擇。所以,Android會默認選擇優先級最高的組件做爲實現組件。 這種狀況下,只要備選組件沒有變化,對於同一個Intent對象而言,其實現組件是固定的,所以,組件管理服務會記錄Intent對象與其實現組件的對照關係,當再次經過相同的Intent對象請求服務時,就能夠跳過組件匹配計算,直接返回實現組件。

意圖機制在觸發器組件中的應用

觸發器組件的功能就是監聽廣播事件的Intent對象,並對其進行簡單的解析和處理。調用組件調用sendBroadcast或sendOrderedBroadcast函數進行事件的廣播。這些事件消息的載體就是Intent對象 用於廣播事件中的Intent對象的Action項,與用於界面組件調用中Intent對象的Action項是徹底分離的。 在觸發器組件的構造中,不存在匹配組件選擇的問題。

小結

Android的意圖機制是Android應用模型的核心,解決了組件間的鏈接問題。經過組件管理服務提供的Intent對象與Intent Filter對象的匹配策略,下降了組件間的耦合度,提供了平臺的靈活性,加強了組件的複用性,從而從根本上減輕了應用開發的負擔。

 

相關文章
相關標籤/搜索