纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Android apk 结构 一款Android APK的结构构成解析

腾讯技术工程   2021-10-06 我要评论
想了解一款Android APK的结构构成解析的相关内容吗腾讯技术工程在本文为您仔细讲解Android apk 结构的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Android,apk,结构,Android,软件生成下面大家一起来学习吧。

eb6d235ec553b953be47babcf3c79214.gif

作者:hockeyli腾讯 PCG 客户端开发工程师

一、 APK 组成解析

在开始解析 Android 构建流程之前我们先来看下构建的最终产物 APK 的整体组成:

373c7fa912fa93d601a2bee46c76ae2d.jpg

APK 主要由五个部分组成分别是:

  • Dex:.class 文件处理后的产物Android 系统的可执行文件
  • Resource:资源文件主要包括 layout、drawable、animator通过 R.XXX.id 引用
  • Assets:资源文件通过 AssetManager 进行加载
  • Library:so 库存放目录
  • META-INF:APK 签名有关的信息

1.1 Apk 分析工具

工欲善其事必先利其器既然想分析 APK 必然少不了好用的工具。

① Android Studio 自带的 APK 分析器

通过 APK 分析器我们可以完成这些操作:

  • 查看 APK 中文件(如 DEX 和 Android 资源文件)的绝对大小和相对大小
  • 了解 DEX 文件的组成
  • 快速查看 APK 中文件(如 AndroidManifest.xml)的最终版本
  • 对两个 APK 进行并排比较

17ea071ebbfe2d53570e88ff4f28ba76.jpg

32b7dc60ca5a947d729733c3149aa1c8.jpg

② ClassyShark 可以做为 AS 自带 APK 分析器的补充帮我们分析 dex 中的详细数据以及查看 APK 中的总方法数以及各个模块的方法数分布。

d2879d43ba14e877bcbd96418f5fcb02.jpg

bd3279cc4853ce9876ff287d19573e5e.jpg

1.2 Dex 知识点拓展

当我们在 Android 查看一个 APK 的时候可以看到右上角有 Defined Methods 和 Referenced Methods但大多数人可能不知道这两者的区别这里简单说明下:

Defined Methods:在这个 Dex 中定义的方法;Referenced Methods:Defined Methods 以及 Defined Methods 引用到的方法。

4ae1ce91df4fdc74510ff8cc805e0c95.jpg

Android 有 64K 引用限制当 type_ids、method_ids 或者 field_ids 超过 65536(64 * 1024)的时候需要进行 dex 分包为了 Dex 的数量尽可能少我们需要尽量实现「Dex 信息有效率」的提升。

Dex 信息有效率 = Defined Methods 数量 / Referenced Methods 数量

fcbd12157381ce3d4fce1f805d3f458a.jpg

二、 构建源码导读

当我们用 Android Studio 进行安装包构建的时候会发现其实是运行了一连串的 Task也就是说其实是这些 task 的配合最终构建出我们的 APK 的。

f7effceb22288a5f0bc954d9b2f21079.jpg

2.1 源码引入

如果我们想更了解 Android 的构建流程对于相关的源码肯定是要有所了解的。那我们如何看到这些 Task 相关的源码呢我们知道 Android 是用 Gradle 进行构建的也就意味着这些 task 其实都是放在 Gradle 中我们想看 Gradle 中源码的话可以在 build.gradle 将 Gradle 进行编译。

compileOnly "com.android.tools.build:gradle:3.0.1"

编译完之后可以在 ApplicationTaskManager#createTasksForVariantScope 中找到创建这些 Task 相关的代码也就意味着顺藤摸瓜找到这些 Task 的真正实现逻辑。

2.2 BuildConfig Task 详解

这里以 BuildConfig 文件的生成为例来梳理下如何查看某个 task 的代码逻辑。

e00bdb38830dbbc72bfabf6040247256.jpg

生成 BuildConfig 文件是通过 ApplicationTaskManager 中通过 createBuildConfigTask 来创建对应的 task。

c3d54f1c5e87e629dd6851b62272d237.jpg

e4274c4ca18605c2cbe68f64718fbf82.jpg

顺着代码逻辑我们找到最终真正实现这个逻辑的是:GenerateBuildConfig 这个 taskGenerateBuildConfig 是继承自 BaseTask这里有个小技巧是Task 中真正的执行逻辑都是在带着 @TaskAction 注解的方法上的所以我们能很快找到对应的 generate() 方法。可以看到生成 BuildConfig 整体的逻辑还是比较简单的其实就是将 build.gradle 中自带的属性以及我们自定义的属性进行读取然后通过 JavaWriter 生成对应的 BuildConfig 文件。

df07f7f471b6ece6c98a1e12b9052de4.jpg

7a1ba666a1140804ce039a0a0364a2c7.jpg

2.3 获取所有 task 对应的类名

看到上面的例子可能有些人会抛出一个疑问就是那我们怎么确定构建中执行的 task 具体对应哪个类呢这里提供一个小技巧其实我们可以在 taskGraph 构建完成之后将所有 task name 以及对应的 class 进行打印。例如在 build.gradle 中加入这个代码之后我们在运行的时候就会把 task 所对应的类名也都一起打印出来。

a377eee7e3d8968efb8d4f609aed5ad3.jpg

222d9ed225de75f9c46600e5ab253fc8.jpg

三、构建流程梳理

44cbf4df08724a4f3247cc0fe276ea86.jpg

可以看到 Android 构建中会涉及到多个工具我们可以通过 open $ANDROID_HOME/build-tools 来查看相关的构建工具。

92871bad7d2fc9268769a14710a1f17e.jpg

四、手动构建 APK

最后我们通过命令行来手动打包一个可执行的 APK能让我们对 APK 构建的理解更加深入。首先需要准备下 代码、资源文件、AndroidManifest 这些构建 APK 的必要文件。

ddaadfa687ef474d71fd94b48e89a5fd.jpg

① 通过 aapt2 compile 将 res 资源编译成 .flat 的二进制文件:

aapt2 compile -o build/res.zip --dir res

② 通过 aapt2 link 将 .flat 和 AndroidManifest 进行连接转化成不包含 dex 的 apk 和 R.java:

aapt2 link build/res.zip -I $ANDROID_HOME/platforms/android-30/android.jar --java build --manifest AndroidManifest.xml -o build/app-debug.apk

③ 通过 javac 将 Java 文件编译成 .class 文件:

javac -d build -cp $ANDROID_HOME/platforms/android-30/android.jar com/**/**/**/*.java

④ 通过 d8 将 .class 文件转化成 dex 文件:

d8 --output build/ --lib $ANDROID_HOME/platforms/android-30/android.jar build/com/tencent/hockeyli/androidbuild/*.class

⑤ 合并 dex ⽂件和资源⽂件:

zip -j build/app-debug.apk build/classes.dex

⑥ 对 apk 通过 apksigner 进行签名:

apksigner sign -ks ~/.android/debug.keystore build/appdebug.apk

欢迎点赞


相关文章

猜您喜欢

  • mysql重复记录数据排查处理 一次现场mysql重复记录数据的排查处理实战记录

    想了解一次现场mysql重复记录数据的排查处理实战记录的相关内容吗AntCredit在本文为您仔细讲解mysql重复记录数据排查处理的相关知识和一些Code实例欢迎阅读和指正我们先划重点:mysql统计重复数据,mysql去除重复数据查询,mysql查询重复的记录下面大家一起来学习吧。..
  • Java线程池使用 Java线程池的简单使用方法实例教程

    想了解Java线程池的简单使用方法实例教程的相关内容吗随身电源在本文为您仔细讲解Java线程池使用的相关知识和一些Code实例欢迎阅读和指正我们先划重点:java线程池使用实例,java线程池使用方式,java线程池使用详解下面大家一起来学习吧。..

网友评论

Copyright 2020 www.Shellfishsoft.com 【贝软下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式