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,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的匹配。中间涉及的数据结构较多,只要大家静下心来分析,相信都是可以很快掌握的。