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

一、 APK 组成解析

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

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 进行并排比较

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

1.2 Dex 知识点拓展

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

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

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

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

二、 构建源码导读

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

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 的代码逻辑。

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

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

2.3 获取所有 task 对应的类名

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

三、构建流程梳理

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

四、手动构建 APK

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

① 通过 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

腾讯程序员视频号最新视频

欢迎点赞

一款 APK 是怎么诞生的?相关推荐

  1. 联想国产自主计算机,实现零的突破,第一款纯国产电脑诞生,网友:此刻联想怎么想?...

    原标题:实现零的突破,第一款纯国产电脑诞生,网友:此刻联想怎么想? 导读:在PC电脑时代,微软牢牢把握操作系统和软件霸主地位,英特尔.惠普.戴尔统治了硬件领域,他们在电脑领域的地位好比三星.苹果和华为 ...

  2. 《王者荣耀》等“爆款”游戏是如何诞生的?| 马晓轶青腾大学演讲

    硅谷Live / 实地探访 / 热点探秘 / 深度探讨 注册用户超2亿,成为全球用户数最多的MOBA(多人在线战术竞技游戏)手游,腾讯的现象级手游<王者荣耀>成绩辉煌. 作为腾讯互娱娱乐事 ...

  3. 一款APK,集成Lighttpd、phpMyAdmin、Drupal7、ownCloud等等工具

     概述:     手机服务站是一款能够在Android设备上搭建Web服务器环境的Android软件,除包含了Web服务器基本的软件(lighttpd.MySQL.php.phpMyAdmin)外 ...

  4. 【 Net Micro Framework PortingKit – 10】世界首款Cortex-M3内核MFV4诞生

    目前在Cortex-M3平台上最常见的嵌入式操作系统就是UCOSII了,除此之外可支持的主流嵌入式操作系统就难以见到了,这是因为Cortex-M3主频较低(常见72M),不支持MMU,片内Flash和 ...

  5. 又一款匿名社交应用诞生:一只“乌鸦”飞来了

    伴随Secret及其"衍生者"的持续火爆,匿名社交应用迅速发展,成移动社交领域新红海.近日,啪啪创始人许朝军推出匿名社交应用产品"乌鸦",旗下产品啪啪已在全站显 ...

  6. 包包设计灵感:一款意蕴深长的手工包包诞生记

    ▲莱佛士设计学院学生作品 或许初见这款包包时,你也许会觉得它好像只是一款简单的手提包. 但当你了解了包包背后的制作过程及灵感来源,你才会了解每一款作品背后的深意.甚至感知到,为何包包的制作者Kawal ...

  7. android apk安装工具,APK安装器下载-APK安装器手机版下载v2.9-1 安卓版-西西软件下载...

    APK安装器取代手机当中自带的APK安装器,让安装的界面在整体上面变得更加的好看,对于颜值有着极高要求的用户而言,虽然安装界面我们不一定能够经常的进行看到,但是界面的丑美也非常影响感官体验,感兴趣的话 ...

  8. [工具向]__androidstudio签名打包apk及配置自动签名

    前言 好几天了,没怎么更新了,最近迷上了抓妖,有些懈怠了,这两天在看android的一些东西,java暂时就先放了放,昨天终于是完成了一个小阶段的任务,今天来对这两天的东西进行一下总结. *** 因为 ...

  9. APK加密方法:某社交类Android APP加密分享

    这款社交类APK是无数宅男宅女的挚爱,但是听说他们对这款app进行了非常严密的保护,防止用户进行二次打包.现在我们就来分析下这款app的安全性到底如何! 工具/原料 APK源码安全检测平台 APK源码 ...

最新文章

  1. Hololens2-OpenXR开发(一)-入门
  2. 东华大学java_东华大学2020秋《Java程序设计》期末大作业
  3. [导入]WCF后传系列(6):消息如何传递之绑定Part 1
  4. CodeForces - 760E Nikita and stack
  5. 如何在一个站点里使用两个Web.sitemap 或是多个Web.sitemap?
  6. 使用gitkraken来push的流程
  7. Winfrom实现圆角设计
  8. 常见人工智能比赛平台总结
  9. Array.forEach
  10. 网易云推出“音街”APP 入局免费K歌市场
  11. linux shell pattern,shell 三剑客之 sed pattern 详解
  12. 【Linux学习010】算数运算、文件测试、字符测试、位置变量和特殊变量
  13. Modbus_TCP网关与组态王连接方法
  14. SQL SERVER STATISTICS
  15. HCIA—网络基本知识—双绞线(文字 + 图解)
  16. 系统设定工具与硬件侦测
  17. 利用bmob实现简单的注册和登录
  18. 烟酰胺与nmn哪个好,nmn烟酰胺单核苷酸的不可替代性,看完醒悟
  19. 2009年最受欢迎的十大系统及相关问题教程
  20. 小度智能音箱维修点_小度在家是哪家公司的_小度在家智能音箱怎么样

热门文章

  1. zookeeper初探二 windows环境搭建伪集群
  2. [09]CSS 边框与背景 (上)
  3. [转]run for a girl
  4. Node.js与Sails~Model数据模型
  5. Android ViewPager
  6. 3月上旬我国域名增长平稳 新增92059个域名
  7. nginx 漏洞(适用于0.1.0-0.8.14)补丁
  8. 牛客 - 奇怪的背包问题增加了(贪心)
  9. POJ - 2480 Longge's problem(欧拉函数+唯一分解定理)
  10. linux算法设计,红黑树的原理分析和算法设计