queryIntentActivities函数的作用:

在Android应用程序开发中,用startActivity可以开启另外一个Activity或应用。startActivity函数必须包含Intent参数,这个参数用来指定具体要打开的组件。

例如,

startActivity(new Intent(this,MyActivity.class));

那么,Android系统是如何进行Intent的匹配的呢?答案主要在PackageManagerService(PMS)的queryIntentActivities函数中。本节来分析queryIntentActivities相关源代码。

queryIntentActivities源码分析:

在启动一个activity时,会通过调用queryIntentActivities来获取activity,例如:

        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags| PackageManager.GET_RESOLVED_FILTER, userId);

相关的数据结构:

ActivityInfo mResolveActivity: 保存Activity相关的信息。例如启动模式,权限......等;ApplicationInfo mAndroidApplication: 应用程序信息;final ResolveInfo mResolveInfo = new ResolveInfo();ComponentName mResolveComponentName: Component组件PackageParser.Package mPlatformPackage; package

queryIntentActivities函数的源代码:

queryIntentActivities函数的代码位置:

frameworks/base/services/java/com/android/server/pm/

源代码:

@Overridepublic List<ResolveInfo> queryIntentActivities(Intent intent,String resolvedType, int flags, int userId) {if (!sUserManager.exists(userId)) return null;ComponentName comp = intent.getComponent();if (comp == null) {if (intent.getSelector() != null) {intent = intent.getSelector(); comp = intent.getComponent();}}if (comp != null) {final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);final ActivityInfo ai = getActivityInfo(comp, flags, userId);if (ai != null) {final ResolveInfo ri = new ResolveInfo();ri.activityInfo = ai;list.add(ri);}return list;}// readersynchronized (mPackages) {final String pkgName = intent.getPackage();if (pkgName == null) {return mActivities.queryIntent(intent, resolvedType, flags, userId);}final PackageParser.Package pkg = mPackages.get(pkgName);if (pkg != null) {return mActivities.queryIntentForPackage(intent, resolvedType, flags,pkg.activities, userId);}return new ArrayList<ResolveInfo>();}}

分析:

1. 获取Component组件实例;

2. comp!=null: 即intent精确匹配,这种情况下,会跳转到具体的activity;

3. 通过调用getActivityInfo来获取ActivityInfo实例;

在getActivityInfo中,再通过调用mActivitys数据成员来获取component对应的activity,代码如下:

@Overridepublic ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {if (!sUserManager.exists(userId)) return null;synchronized (mPackages) {PackageParser.Activity a = mActivities.mActivities.get(component);if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {PackageSetting ps = mSettings.mPackages.get(component.getPackageName());if (ps == null) return null;return PackageParser.generateActivityInfo(a, flags, ps.getStopped(userId),ps.getEnabled(userId), userId);}if (mResolveComponentName.equals(component)) {return mResolveActivity;}}return null;}

另外,还可以参考如下博文:

Android源码分析-PackageManagerService(PMS)源码分析(一)PMS的初始化以及PackageManager的使用

Android源码分析-PackageManagerService(PMS)源码分析(二)- 利用PackageParser进行package的解析

Android源码分析-PackageManagerService(PMS)源码分析(三)- queryIntentActivities函数来查找activity相关推荐

  1. STL 源码分析: RB_tree 红黑树(三) 插入和查找

    不管什么样的插入,在插入新的节点后都考虑红黑树的四条约束是否被破坏,于是需要通过更改节点的颜色和子树的形状来使得红黑树的四条性质重新获得满足. 首先介绍两个旋转函数:左旋和右旋. 我们先看两个函数的原 ...

  2. 【Android 逆向】整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )

    文章目录 前言 一.DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 二./bin/dexopt 源码分析 前言 上一篇博客 [Android 逆向]整体加固脱壳 ...

  3. 【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 二 | AMS 进程相关源码 | 主进程相关源码 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  4. 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 )

    文章目录 一.回调 StateChangedListener 接口 二.JobHandler 处理 ( 任务检查 ) 三.maybeRunPendingJobsH 方法 四.assignJobsToC ...

  5. 【Android 性能优化】应用启动优化 ( 阶段总结 | Trace 文件分析及解决方案 | 源码分析梳理 | 设置主题的方案总结 ) ★

    文章目录 一. 常用的耗时方法优化方案 ( 重要 ) 二. 源码分析梳理 1. 应用启动时间计算相关源码分析 2. Launcher 应用中启动 Android 应用流程 三. 启动白屏解决方案 An ...

  6. Android 广播接收器注册与注销源码分析

    注册广播接收器 Android系统的广播机制是一种消息订阅/发布机制,因此,使用这种消息驱动模型的第一步便是订阅消息:而对Android应用程序来说,订阅消息其实就是注册广播接收器.在Android的 ...

  7. Android 9 (P) Zygote进程启动源码分析指南二

         Android 9 Zygote进程启动源码分析指南二 Android 9 (P) 系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 Andro ...

  8. 【Android】Android Binder进程间通信AIDL示例与源码分析

    前言 众所周知,Android进程间通信采用的是Binder机制.Binder是Android系统独有的进程间通信方式,它是采用mmp函数将进程的用户空间与内核空间的一块内存区域进行映射,免去了一次数 ...

  9. android 点击事件消费,Android View事件分发和消费源码简单理解

    Android View事件分发和消费源码简单理解 前言: 开发过程中觉得View事件这块是特别烧脑的,看了好久,才自认为看明白.中间上网查了下singwhatiwanna粉丝的读书笔记,有种茅塞顿开 ...

最新文章

  1. 二分图 ---- 树的二分图性质 2020icpc 济南 J Tree Constructer(构造)
  2. 从指定文件夹里COPY指定的一批文件列表(TXT文件)
  3. Nginx+PHP7 安装及配置
  4. 执行超时已过期。完成操作之前已超时或服务器未响应。_OMG! 云服务器 CPU 100%了!肿么办?...
  5. CloudCare容器技术白皮书
  6. WebRTC视频数据流程分析
  7. 常用工具说明--搭建基于rietveld的CodeReview平台(未测试)
  8. 1423. 可获得的最大点数
  9. 更多和最小生成树相关的问题
  10. CSS:结合clip-path实现目录的隐藏显示以及提示框的隐藏显示
  11. mysql 面试知识点笔记(三)联合索引的最左匹配原则
  12. 选择交换法排序c语言程序,C语言排序算法之简单交换法排序,直接选择排序,冒泡排序...
  13. android studio如何连接夜神模拟器
  14. CRM学习笔记类转换工具(pojo互转)上下文中获取用户名cookie工具
  15. Hbuilder上架苹果app流程(上)
  16. 搜索算法——双向bfs
  17. Codeforces 416C Booking System
  18. 基础实验7-2.1 魔法优惠券 (贪心)
  19. Panda3d如何获取到可用的模型?Maya、3D Max、OBJ等3D格式转换为egg、gltf文件
  20. 阿里云OSS 图片处理api(custom)

热门文章

  1. 【Python】开发笔记
  2. 通达信版弘历软件指标_弘历软件多空王指标
  3. Ubuntu wps 安装及 windows字体安装
  4. 短视频直播平台第三方特效SDK接入教程(完整版)
  5. 2021-05-12 MongoDB面试题 应该启动一个集群分片(sharded)还是一个非集群分片的 MongoDB 环境
  6. Linux 下压缩包解压后目录的权限问题
  7. 电脑文件管理——XYplorer
  8. java poi生成word
  9. RTKLIB专题学习(七)---精密单点定位实现初识(三)
  10. Mac电脑批量修改图片名称