PackageManager的intent匹配查詢流程

上一篇文章我們分析了PackageManager應用程序權限管理,包括runtime權限等等,今天我們分析下packageManager是怎樣查詢匹配intent。

本章設計源碼路徑:

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
frameworks/base/services/core/java/com/android/server/ IntentResolver.java
frameworks/base/core/java/android/app/ApplicationPackageManager.java

intent查詢匹配

intent查詢主要是查詢匹配某Intent的Activities,BroadCastReceiversServices等。

首先我們需要瞭解到PKMS的數據結構,他對於activity的管理如下,不知道的戳這裏複習:

android M PackageManagerService 啓動過程分析

android M PackageManager對於應用程序apk的安裝流程分析

PKMS在掃描apk時,會將解析得到pkg私有的activity信息加入到自己的數據結構mActivities中保存:




從上面的代碼可知,mActivitiesActivityIntentResolver類型,是PKMS的成員變量,用於保存系統中所有與Activity相關的信息。此數據結構內部有一個mActivities變量,它以ComponetNameKey,保存PackageParser.Activity對象。

APK中解析得到的所有和Activity相關的信息(包括在XML中聲明的IntentFilter標籤)都由PacakgeParser.Activity來保存。

如上,addActivity的實現中,將Component和Activity保存到mActivities中,而PackageParser.ActivityIntentInfo則存儲了所有xml聲明的intentFilter信息。

說明:

  • mFilters:用於保存所有IntentFilter信息;
  • mSchemeToFilter:用於保存URI中與schema相關的IntentFilter信息。
  • mActionToFilter:用於保存僅設置Action條件的IntentFilter信息。
  • mTypedActionToFilter:用於保存既設置了Action又設置了Data的MIME類型的IntentFilter信息。
  • mWildTypeToFilter:用於保存設置了Data類型類似“image/*”的IntentFilter,但是設置MIME類型類似“Image/jpeg”的不算在此類。
  • mTypeToFilter:除了包含mWildTypeToFilter外,還包含那些指明瞭Data類型爲確定參數的IntentFilter信息,例如“image/*”和”image/jpeg“等都包含在mTypeToFilter中。
  • mBaseTypeToFilter:包含MIME中Base 類型的IntentFilter信息,但不包括Sub type爲“*”的IntentFilter

舉例說明這些filter的用法,假設在xml中有如下一段intent-filter信息:


那麼在mTypedActionToFilter中能夠以”android.intent.action.VIEW”爲key匹配到該intentFilter

mWildTypeToFiltermTypeToFilter中能夠以“audio”key找到該IntentFilter

mSchemeToFilter中能夠以”http“key找到該IntentFilter

Intent匹配查詢工作

客戶端可以通過ApplicationPackageManager提供的API來查詢具備要求的activity。

queryIntentActivitiesAsUser通過mPm的binder調用,最終到了PKMS的queryIntentActivities方法中。


這個方法分三種情況:

1.顯示Intent:如果查詢的intent中攜帶component信息則很簡單,通過getActivityInfo就可以得到符合要求的數據,將其封裝在ResolvedInfo中返回給調用者。

2.半隱式:即指明瞭pkgName,則會調用queryIntentForPackage在該pkg包含的Activity中查詢。

3.隱式Intent:上面兩個條件都不滿足,則會調用mActivities的queryIntent在全局範圍內來查找匹配。

我們重點分析這個方法。

由於mActivities是ActivityIntentResolver類型,因此queryIntent則是該類中的方法了,而ActivityIntentResolver是IntentResolver的子類,queryIntent方法最終調用的是基類的queryIntent。故而轉向IntentResolver的queryIntent方法,其方法體如下:


從上面看出,action的優先級最低,然後依次根據匹配的intent構建ResolveList,最終存儲到finalList中排序後返回給調用者。

信息查詢小結

這裏主要分析了activity的查找過程,其他組件類似,就是進行Intent的匹配。中間涉及的數據結構較多,只要大家靜下心來分析,相信都是可以很快掌握的。

發佈了36 篇原創文章 · 獲贊 22 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章