上一篇文章我們分析了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,BroadCastReceivers,Services等。
首先我們需要瞭解到PKMS的數據結構,他對於activity的管理如下,不知道的戳這裏複習:
android M PackageManagerService 啓動過程分析
android M PackageManager對於應用程序apk的安裝流程分析
PKMS在掃描apk時,會將解析得到pkg私有的activity信息加入到自己的數據結構mActivities中保存:
從上面的代碼可知,mActivities爲ActivityIntentResolver類型,是PKMS的成員變量,用於保存系統中所有與Activity相關的信息。此數據結構內部有一個mActivities變量,它以ComponetName爲Key,保存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。
在mWildTypeToFilter和mTypeToFilter中能夠以“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的匹配。中間涉及的數據結構較多,只要大家靜下心來分析,相信都是可以很快掌握的。