PackageManager的intent匹配查询流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huilin9960/article/details/80693769

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

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页