文中涉及到的工具所在目录:Android/sdk/build-tools。下面开始分解并逐步实现对源码的打包。

编译流程

1. 生成仅包含资源文件的 apk 包和 R.java 文件

根据资源文件和 AndroidManifest.xml 由工具 AAPT 生成 R.java 文件。Android Gradle Plugin 3.0.0 以后默认使用 AAPT2,详见 AAPT2 官方文档。来看一下 AAPT2 的使用:

预编译

编译所有 Android 支持的资源文件。可以通过编译语句将单个资源文件编译成 .flat 后缀的过渡二进制文件

AAPT 可以编译单个文件,例如编译 strings.xml,会生成 values_strings.arsc.flat 文件:

aapt2 compile app/src/main/res/values/strings.xml -o test/

  

但一个项目不可能只有一个资源文件,通常都是编译 整个 res 资源目录,会生成 zip 压缩包,包含了所有资源文件编译后的 flat 格式文件:

aapt2 compile --dir app/src/main/res/ -o package/res.zip

  

参数含义:

  • —dir:指定输入目录

  • -o: 指定输出目录(如果输入源是文件夹,则需要指定编译后的(zip)文件名)

链接(link)

将预编译生成的过渡二进制文件合并并打包成单独的 APK 包,R 文件和 ProGuard 规则文件也是在这个时期生成的,生成的 APK 包不包含 DEX 字节码并且是未签名的(后续可使用 D8 编译工具将 Java 字节码编译成 DEX 字节码,使用 apksigner 对 APK 签名)

aapt2 link package/res.zip \
-I ~/Library/Android/sdk/platforms/android-27/android.jar \
--java package/ \
--manifest app/src/main/AndroidManifest.xml \
-o package/res.apk

  

参数含义:

  • -I:必要参数,指定 android.jar 目录,因为 xml 中可能使用到了例如 android:id 等自带的 android 命名空间

  • o:指定输出 apk 路径

  • —java:指定生成的 R 文件的路径

  • —manifest:必要参数,Manifest 文件中包含了 app 的包名和 application id

执行上述命令后报错:style/Theme.AppCompat.Light.DarkActionBar not found.

以及 layout_constraintBottom_toBottomOf (新建的工程默认依赖了 constraint-layout库)等各种 not found。

报这些错是因为 link 时没有引入第三方库,在 Google 文档里没有找到相关的命令,所以先移除这些依赖,跑通整个流程后再回头看怎么解决。

// AppTheme 暂时先移除对 Theme.Appcompat 的依赖
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
</style>

  

再执行一遍命令,可以看到指定的输出目录已经生成了 apk 包和 R 文件:

2. 处理aidl,生成对应的java文件

因为 demo 没有涉及到 aidl,暂且跳过。

3. 编译 .java 文件为 .class 文件

编译项目 src 目录下所有 .java 文件还有之前生成的 R.java 、aidl 生成的 java 文件为相应的的 class 文件

javac -encoding utf-8 \
-target 1.8 \
-bootclasspath ~/Library/Android/sdk/platforms/android-27/android.jar \
app/src/main/java/com/yazhidev/demo/*.java package/com/yazhidev/demo/R.java \
-d package/

  

参数含义:

  • -encoding: 指定编码方式为 uts-8

  • -target:指定 Java 版本号

  • -bootclasspath:引入 Android.jar 包内的类

  • -d:指定编译生成的字节码文件存放的路径

4. class 文件编译为 dex 文件

dex 文件是 Android 虚拟机所能识别、解析并运行的文件。Java 源文件被编译为 class 文件后,需要通过 dex 编译器将多个 class 文件整合为一个 dex 文件,从 Android Studio 3.1 开始,已经使用 D8 替代原先的 DX 作为默认的 dex 编译器。D8 的使用很简单:

d8 package/com/yazhidev/demo/*.class \
--classpath ~/Library/Android/sdk/platforms/android-27/android.jar \
--output ./

  

参数含义:

  • —classpath:指定编译需要引用到的类

  • —output:指定编译后生成的 .dex 文件的存放路径

5. 将 dex 文件添加进 apk 包

原本这步是通过 apkbuilder 脚本来做的,现在改成用 aapt 命令来做。

aapt add package/res.apk classes.dex

  

需要注意的是 dex 文件前不能加路径,否则会将路径带入 apk 包中。

6. 优化对齐 apk 文件

apksigner 文档中提到,如果使用 apksigner 对 apk 签名,则需要在签名之前使用 zipalign 优化对齐。

zipalign 的使用很简单:

zipalign 4 package/res.apk package/app-unsigned-aligned.apk

  

4 代表 32 位对齐,zipalign 可以确保所有未压缩的数据的开头均相对于文件开头部分执行特定的字节对齐,这样可减少应用消耗的 RAM 量。

7. 签名

签名需要私钥,可以通过 Android Studio 生成,也可通过 JDK bin 目录下的 keytool 工具生成。keytool 以及 apksigner 的使用可参考:从命令行构建和签署您的应用

我自己这么就直接使用现有的 key 签名,签名的命令很简单:

//apk 签名
apksigner sign --ks key.jks --out package/app-release.apk package/app-unsigned-aligned.apk

  

参数含义:

  • —ks:指定私钥文件

  • —out:指定签名后的 apk 输出路径

//检查 apk 的签名apksigner verify app.apk

  

至此,就完成了 Android 源码打包成 apk 的整个流程,当然以上只是最简单的情况,对于第三方库、多 module 等情景下的打包流程都没有涉及。将 apk 安装到手机上,可以正常打开

源:http://www.manongjc.com/article/59926.html

从 Android 源码到 apk 的编译打包流程的更多相关文章

  1. APK 的前世今生:从 Android 源码到 apk 的编译打包流程

    最近想要研究热修复的原理,并自己实现一套简单的热修复框架(音视频的坑刚挖好就又挖另一个坑了2333),已经在看书入门 c++,方便后续查看业内一些知名热修复框架的源码,另外在涉及编译期/运行时修改代码 ...

  2. Atitit.反编译apk android源码以及防止反编译apk

    Atitit.反编译apk android源码以及防止反编译apk 1.1. Tool  apk逆向助手1 1.2. 二.使用dex2jar + jd-gui 得到apk的java源码1 1.3. 用 ...

  3. 【转】Android 源码下利用jni编译自己的项目(参考系统development/samples/SimpleJNI)

    原文网址:http://blog.csdn.net/qiuxiaolong007/article/details/7860481 记于正文前:环境是ubuntu10.10,android 源码是2.0 ...

  4. 2014年最新720多套Android源码2.0GB免费一次性打包下载

    之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...

  5. Android源码的下载和编译

    由于公司会安排我做硬解码这块,所以最近一直想研究一下Android源码,可是Android源码的下载真的挺麻烦的(可能是我第一次下载),参照网上的方法,没有一个可行的,现在就将我的下载过程和大家分享一 ...

  6. 关于android源码中的APP编译时引用隐藏的API出现的问题

    今天在编译android源码中的计算器APP时发现,竟然无法使用系统隐藏的API,比如android.os.ServiceManager中的API,引用这个类时提示错误,记忆中在android源码中的 ...

  7. Android源码的下载、编译与导入到Android Studio【转】

    本文转载自:http://wl9739.github.io/2016/05/09/Android%E6%BA%90%E7%A0%81%E7%9A%84%E4%B8%8B%E8%BD%BD%E3%80% ...

  8. Android源码分析(八)-----系统启动流程&IPC简述

    一 :系统启动流程图 从下往上依次启动linux kernel -->zygote-->SystemServer-->NativeService-->AndroidServic ...

  9. 转--2014年最新810多套android源码2.46GB免费一次性打包下载

    转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源 ...

随机推荐

  1. Django Model模型

    Model简介 模型准确且唯一的描述了数据.它包含您储存的数据的重要字段和行为.一般来说,每一个模型都映射一张数据库表. 每个模型都是一个 Python 的类,这些类继承 django.db.mode ...

  2. DS1302时钟基础使用(含代码)

    了解其管脚 X1 X2 32.768KHz 晶振管脚 GND 地 RST 复位脚 I/O 数据输入/输出引脚,具有三态 SCLK 串行时钟 Vcc1,Vcc2(备用电源供电) 电源供电管脚 DS130 ...

  3. springboot-多环境测试

    1.application.properties中添加spring.profiles.active=test 2.同级目录下创建application-dev.properties.applicati ...

  4. docker容器内存和CPU使用限制

    docker容器内存和CPU使用限制 示例如下 sudo docker run --name seckill0 -p 8080:8080 -m 1024M --cpus=0.2 -d seckill: ...

  5. guns系统部署方式及常见问题

    项目框架:guns 开发IDE:Idea 2018.1 两种打包方式:war 和jar. 1.正常打包的姿势 1.1按照下图修改为你想到打包的方式. ​ 1.2 执行打包 ​​ clean packa ...

  6. Docker部署Nextcloud私有网盘

    对于国内某度的网盘限速行为大家有目共睹,不过对于商业化的产品模式这样也无可厚非,毕竟企业也是盈利为目的.如果想享受互联网技术带来的便利,刚好也懂一点技术的话可以尝试搭建属于私有的网盘.个人比较推荐的是 ...

  7. elasticsearch 7.1 401 Unauthorized

    1.执行curl -XGET 'localhost:9200/_cat/indices?v&pretty'  报401 2.修改配置xpack.security.enabled: false ...

  8. 关于MYSQL安装踩的坑

    前提:本人装的版本是mysql-8.0.18-winx64,win10系统,如果你安装的是其他版本的MYSQL,语法会跟下面有些许区别: 一,安装 https://dev.mysql.com/down ...

  9. ZOJ Problem Set - 1004

    1.翻译参考 http://liucw.blog.51cto.com/6751239/1198026 2.代码参考 http://www.cnblogs.com/devymex/archive/201 ...

  10. 12.Flume的安装

    先把flume包上传并解压 给flume创建一个软链接 给flume配置环境变量 #flume export FLUME_HOME=/opt/modules/flume export PATH=$PA ...