【Android】点击应用进而打开base.apk的调用流程再分析

2023-10-27


点击一个应用的时候,会加载其对应的base.apk,我们在AssetManager类的addAssetPath方法中添加堆栈打印,

其调用堆栈为

android.content.res.AssetManager.addAssetPath(AssetManager.java:653)

 android.app.ResourcesManager.getTopLevelResources(ResourcesManager.java:221)

 android.app.ActivityThread.getTopLevelResources(ActivityThread.java:1854)

 android.app.LoadedApk.getResources(LoadedApk.java:558)

 android.app.ContextImpl.<init>(ContextImpl.java:1884)

 android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1733)

 android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1718)

 com.android.server.AttributeCache.get(AttributeCache.java:114)

 com.android.server.am.ActivityRecord.<init>(ActivityRecord.java:564)com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1763)

com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:1153)

com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4271)

 com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:4258)

 android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:168)

 com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2703)

 

分析这个堆栈信息,我们来追根溯源的查看AssetManager对象的创建过程。

第一次打开应用的时候,调到ActivityManagerService的startActivityAsUser方法,

后来调到com.android.server.am.ActivityRecord.<init>(ActivityRecord.java:564)

564 AttributeCache.Entry ent = AttributeCache.instance().get(packageName,

565              realTheme,com.android.internal.R.styleable.Window, userId);

继续调用

com.android.server.AttributeCache.get(AttributeCache.java:114)

查看AttributeCache.java

112 Context context;

113 try {

114     context =mContext.createPackageContextAsUser(packageName, 0,

115             new UserHandle(userId));

116     if (context == null) {

117         return null;

118     }

119 } catch (PackageManager.NameNotFoundExceptione) {

120     return null;

121 }

122 pkg = new Package(context);

123 mPackages.put(packageName, pkg);

在这里,mPackages是一个map,其定义为

        private final WeakHashMap<String,Package> mPackages =

            newWeakHashMap<String, Package>();

在Android 7上,修改为了

    private finalArrayMap<String, WeakReference<Package>> mPackages = newArrayMap<>();

 

在114行,变量context指向了mContext.createPackageContextAsUser(packageName, 0, newUserHandle(userId));的返回值

在122行对context进行了引用。

 

114行调用到android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1718)

继续调用到

android.app.ContextImpl.createPackageContextAsUser(ContextImpl.java:1733)

查看ContextImpl.java

1733     ContextImpl c = new ContextImpl(this,mMainThread, pi, mActivityToken,

1734   user, restricted, mDisplay, null,Display.INVALID_DISPLAY, themePackageName);

 

1733行又调用到

android.app.ContextImpl.<init>(ContextImpl.java:1884)

查看ContextImpl.java

1884         Resources resources =packageInfo.getResources(mainThread);

1906         mResources = resources;

新创建的ContextImpl对象的成员变量mResources对resources进行了引用。

 

1884行继续调用

android.app.LoadedApk.getResources(LoadedApk.java:558)

android.app.ActivityThread.getTopLevelResources(ActivityThread.java:1854)

android.app.ResourcesManager.getTopLevelResources(ResourcesManager.java:221)

查看ResourcesManager.java

211         AssetManager assets = newAssetManager();

 

218         // already.

219         if (resDir != null) {

220  

221             if (assets.addAssetPath(resDir) ==0) {

222                 return null;

223             }

224         }

 

301         r = new Resources(assets, dm, config,compatInfo);

 

319             return r;

 

终于,找到了AssetManager创建的地方了,然后创建了C++层的AssetManager对象,再调用addAssetPath方法加载了base.apk

在Resources.java中有

   public Resources(AssetManager assets, DisplayMetrics metrics,Configuration config,  CompatibilityInfocompatInfo) {

        mAssets = assets;

        mMetrics.setToDefaults();

        if (compatInfo != null) {

            mCompatibilityInfo = compatInfo;

        }

        updateConfiguration(config, metrics);

        assets.recreateStringBlocks();//Modified for ThemeManager

   }

Resources中的mAssets对新创建的AssetManager对象进行了引用
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Android】点击应用进而打开base.apk的调用流程再分析 的相关文章

随机推荐

  • java string 转小写_Java String toLowerCase()(String转小写)与示例 - Break易站

    Java 字符串 Java String toLowerCase String转小写 与示例 Java字符串toLowerCase 方法中的字符串的所有字符转换为小写字母 有两种类型的toLowerCase 方法 签名 public Str
  • 通俗讲解:什么是Web

    转自 微点阅读 https www weidianyuedu com content 1017370521955 html 简单的说Web就是为用户提供的一种在互联网上浏览信息的服务 Web服务是动态的 可交互的 跨平台的和图形化的 Web
  • vscode安装_VsCode安装shader glsl环境

    在扩展tab中搜索Shader languages support for VS Code sls for vs code插件 2 安装后搜索glsl canvas 并安装 glsl canvas插件 至此环境安装完成 可新建个工程测试 测
  • v-model cannot be used on v-for or v-slot scope variables because they are not writable报错问题解决方案

    报错 错误代码 div div
  • redis 集合排重_使用Redis的有序集合实现排行榜功能

    游戏中存在各种各样的排行榜 比如玩家的等级排名 分数排名等 玩家在排行榜中的名次是其实力的象征 位于榜单前列的玩家在虚拟世界中拥有无尚荣耀 所以名次也就成了核心玩家的追求目标 一个典型的游戏排行榜包括以下常见功能 能够记录每个玩家的分数 能
  • ros tf

    欢迎访问我的博客首页 tf 1 tf 命令行工具 1 1 发布 tf 1 2 查看 tf 2 参考 1 tf 命令行工具 1 1 发布 tf 我们根据 cartographer ros 的 launch 文件 backpack 2d lau
  • 【Python】《Python编程:从入门到实践 (第2版) 》笔记-Chapter2-变量和简单数据类型

    二 变量和简单数据类型 在程序中可随时修改变量的值 而Python将始终记录变量的最新值 message Hello Python world print message message Hello Python Crash Course
  • hashCode的性能优化

    本文主要讨论下不同的hashCode 实现对应用程序的性能影响 hashCode 方法的一个主要作用就是使得对象能够成为哈希表的key或者散列集的成员 但同时这个对象还得实现equals Object 方法 它和hashCode 的实现必须
  • visio图标_弱电间机柜原型图整理,可编辑!(Excel,visio,CAD)

    有朋友问到机柜原型图 这个我们在弱电vip技术群里面也有朋友提到过 今天我们就整理了弱电系统中常用的机柜原型图 有Excel visio CAD版本 可以修改编辑 1 Excel机柜原型图 可编辑 机柜布局 1 机柜布局 2 机柜布局 3
  • C++全局对象初始化依赖关系处理

    class A private int m nSize public A m nSize 100 m pList new char 4 memset m pList 0 sizeof 4 sizeof char int GetSize re
  • 使用基础粒子群(PSO)算法求解一元及二元方程的Python代码

    最近在看清风的数学建模视频 其中有两道题 求一元函数的最值问题 题目 求函数 y 11 s i n x
  • 小谈Intel SGX

    目录 Intel SGX简介 背景 为什么要Intel SGX Intel SGX尚处于学术讨论 Intel SGX和可信启动什么关系 开发者眼中SGX长什么样子 SGX访问控制是什么 MEE与SGX EPC内存加密 CPU里面SGX长什么
  • 深度学习笔记(一):环境(yolov5)配置

    前言 本文为笔者在学习深度学习 进行环境配置时集各家所长总结的一些经验 旨在能够较快的配置好深度学习所需的环境 一 软件安装 1 1 Anaconda安装 直接在官网下载 Anaconda官网链接 安装包下载完毕后 进行安装 更改安装路径
  • CSS属性纪要

    1 line height 行高 跟font size属性的大小有关 一般可用来设置元素垂直居中 1 单行文字或单张图片的垂直居中 div 你好你好 div 以以上代码为例 设置box和height和line height高度一样就可以垂直
  • 原子锁

    Windows核心编程 Interlocked原子访问系列函数 http blog csdn net zhongguoren666 article details 7542975 InterlockedExchange http blog
  • 时间序列的数据分析(一):主要成分

    时间序列是一组按照时间发生先后顺序进行排列 并且包含一些信息的数据点序列 在时间序列数据中通常包含了数据的发展趋势 向上 向下 保持 和数据的变化规律 季节性 等特征 而这些特征往往具有一定的规律性和可预测性 具体来说时间序列数据具有如下几
  • BES2300 代码主架构笔记

    1 BES的内核用的是RTX的内核 并且用了ARM推广的CMSIS RTOS API接口 这样做的好处是可以方便内核的更换 方便移植上层代码 2 程序是从RTX CM LIB H里面的 main init 开始的 里面包括了内核的初始化 堆
  • 【更新指南】BarTender正式迎来2019 R2重大版本更新!

    BarTender 在 150 多个国家 地区拥有成千上百的用户 在标签 条形码 证卡和 RFID 标记的设计和打印领域是全球首屈一指的软件 BarTender 既可以单独运行 也可以与任何其他程序集成 几乎是所有按需打印或打标应用的完美解
  • 国泰安下载数据太大?stata传不进来?

    除了换电脑还有啥方法 其实就是一个小的tip 善用国泰安的条件筛选功能 只愿大家可以从下面的小例子中获取点扩展思维 例如最常用的财务报表数据 国泰安默认的是季度数据 但大多数时候我们需要的只是年度数据 那么我们就可以在条件筛选处加一个 不要
  • 【Android】点击应用进而打开base.apk的调用流程再分析

    点击一个应用的时候 会加载其对应的base apk 我们在AssetManager类的addAssetPath方法中添加堆栈打印 其调用堆栈为 android content res AssetManager addAssetPath As