apk构建过程_apk构建流程_qq_37776700
CSDN话题挑战赛第2期
参赛话题:面试宝典
文章目录
1. 构建系统2. 构建步骤2.1 aapt22.1.1 寻找资源ID2.1.2 资源的分类 2.2 AIDL2.3 SourceCode编译2.4 生成apk2.5 签名 3. gradlew1. 构建系统
APK 打包的内容主要有:应用模块也就是自己开发的用到的源代码、资源文件、aidl 接口文件,还有就是依赖模块即源代码用到的第三方依赖库如:aar、jar、so 文件
2. 构建步骤
2.1 aapt2
AAPT2(Android Asset Packaging Tool):Android 资源打包工具
AndroidSDK/build-tools/31.0.0/aapt2.exe
Android Gradle 插件 3.0.0 以上会默认启用 AAPT2,AAPT2 支持通过启用增量编译实现更快的资源编译。这是通过将资源处理拆分为两个步骤来实现的
编译(compile):将资源文件编译成二进制文件链接(link):合并所有已编译的文件并将它们打包到一个软件包中编译(compile)
将资源文件res
目录下的文件编译成.arsc.flag
或.flat
的二进制文件
aapt2 compile MyApplication/app/src/main/res/values/strings.xml -o compiled/
aapt2 compile MyApplication/app/src/main/res/drawable/myimage.png -o compiled/
-o:指定已编译资源的输出路径(前提是该路径必须存在,否则编译不通过)
上述第一个命令产出 --> values_strings.arsc.flat
上述第二个命令产出 --> drawable_myimage.png.flat
链接(link)
合并在编译阶段生成的所有中间文件(如资源表、二进制 XML 文件和处理过的 PNG 文件),并将它们打包成一个 APK。另外还会生成 R.java
和 ProGuard 规则文件,但是生成的 APK 不包含 DEX 字节码且未签名,也就是说,无法将此 APK 部署到设备
aapt2 link -o output.apk
-I android_sdk/platforms/android-31/android.jar
compiled/res/values_values.arsc.flat
compiled/res/drawable_Image.flat --manifest /path/to/AndroidManifest.xml -v
-o:指定链接的资源 APK 的输出路径
-I:提供平台的 android.jar 或其他 APK(如 framework-res.apk)的路径
--manifest:指定要构建的 Android 清单文件的路径
-v:可提高输出的详细程度
上述命令在当前目录生成一个out.pak,无法部署到设备上
2.1.1 寻找资源ID
目前版本R文件位置:
build/intermediates/compile_and_runtime_not_namespaced_r_class_jar/R.jar
解压后用Androidstudio编译器可查看
如何解决资源冲突
// library Module的build.gradle中设置资源前缀
android{
resourcePrefix "<前缀>"
}
2.1.2 资源的分类
直面底层 Apk是如何生成的?
2022-9-22 19:35:21
Android的资源分为两个部分:assets
和res
,保存的是一些原始的文件,并且不会压缩保持原始状态打包进apk文件中
AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open("myimage.png");
res目录下就有很多其它目录了,animator
、anim
、color
、raw
、layout
等,这其中除了raw和mipmap下的Bitmap资源外,其它均会被aapt2编译成二进制格式的XML文件
aapt2的编译流程主要是以下几个流程:
- 解析 AndroidManifest.xml,获得应用程序的包名称,创建资源表添加被引用资源包,被添加的资源会以一种资源 ID 的方式定义在 R.java 中资源打包工具创建一个 AaptAssets 对象,收集当前需要编译的资源文件,收集到的资源保存在 AaptAssets 对象对象中将上一步 AaptAssets 对象保存的资源,添加到资源表 ResourceTable 中去,用于最终生成资源描述文件 resources.arsc编译 values 类资源,这类资源包括数组、颜色、尺寸、字符串等值给 style、array 这类资源分配资源 ID编译 XML 资源文件,编译的流程分为:① 解析 XML 文件 ② 赋予属性名称资源 ID ③ 解析属性值 ④ 将 XML 文件从文本格式转换为二进制格式生成资源索引表 resources.arsc
2.2 AIDL
AIDL(Android Interface Denifition Language):Android接口定义语言
AndroidSDK/build-tools/31.0.0/aidl.exe
使用aidl
命令可以将AIDL文件转换为java
接口
aidl -Iaidl -AndroidSDK/platforms/android-31/framework.aidl -obuild aidl/com/android/vending/billing/IInAppBillingService.aidl
-I 指定 import 语句的搜索路径,注意 -I 与目录之间一定不要有空格
-p 指定系统类的 import 语句路径,如果是要用到 android.os.Bundle 系统的类,一定要设置 sdk 的 framework.aidl 路径
-o 生成 java 文件的目录,注意 -o 与目录之间一定不要有空格,而且这设置项一定要在 aidl 文件路径之前设置
2.3 SourceCode编译
源代码编译分为两步,分别是将java代码编译成class文件、将Class文件编译成Dex文件
- 将 Java 代码编译成 Class 文件
使用Javac把项目中所有的Java代码编程成.class
文件,包括.java文件
、R.java
以及AIDL生成的Java接口文件
AndroidStudio/jre/bin/javac.exe
javac -target 1.8 -bootclasspath platforms/android-31/android.jar -d ./java/com/testjni/*.java
- 将 Class 文件编译成 Dex 文件
Android Studio 和 Android Gradle 插件使用该工具来将项目的 Java 字节码(包括三方库中的class文件)编译为在 Android设备上运行的 DEX 字节码,该工具支持您在应用的代码中使用 Java 8 语言功能,该过程主要是将Java字节码转成ART字节码
AndroidSDK/build-tools/31.0.0/lib/d8.jar
java -jar d8.jar --dex --ouput=classes.dex ./java/com/testjni/*.class
--dex:将 class 文件转成dex文件
--output:指定生成 dex 文件到具体位置
2.4 生成apk
使用Apkbuilder
,将所有的Dex文件、Resource.arsc、Res文件夹、Assets文件夹、AndroidManifest.xml打包成apk文件(未签名)
Android\SDK\tools\lib\sdklib-26.0.0-dev.jar
apkbuilder为一个脚本文件,实际调用的是(Android\SDK\tools\lib\sdklib-26.0.0-dev.jar)文件中的com.android.sdklib.build.ApkbuilderMain类
2.5 签名
对于apk,使用apksigner
,对于App Bundle,使用jarsigner
。无论哪种方式,都需要使用keytool
生成一个私钥
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
输入上述命令后会提示输入私钥密码,并提示在DistinguishedName字段中给私钥输入相应的名称。之后就会生成一个`my-relese-key.jks`的密钥文件
对apk签名的步骤为
- 使用
zipalign
对齐未签名的apkzipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk
zipalign 可以确保所有未压缩数据的开头均相对于文件开头执行特定的字节对齐,从而减少应用占用的 RAM 量
- 通过
apksigner
用私钥给apk签名apksigner sign --ks my-release-key.jks --out my-app-release.apk my-app-unsigned-aligned.apk
上述命令会输出一个`my-app-release.apk`的apk文件
apksigner
工具支持其他签名方法,包括使用单独的私钥和证书文件为 APK 文件签名,以及由多个签名者为 APK 签名
3. gradlew
从命令行构建您的应用 | Android 开发者 | Android Developers (google.cn)
以上的打包过程中的aidl以及源码编译部分,以及改成bundletool
工具来构建app bundle,而apk的构建可以使用assemble
的方式进行构建
C:\Users\Administrator>gradle
JAVA_HOME is set to an invalid directory
这个问题是由于JAVA_HOME的目录带了bin,以及gradle目录带了bin,导致,把两个的配置路径都去掉\bin即可
C:\Users\Administrator>gradle
'gradle' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
这个坑是由于当前执行gradle
或者gradlew
的目录不是项目根目录造成,切换到项目根目录执行该命令即可
构建release版本的软件包或apk:
如果是apk,则需要zipalign
和apksigner
。签名可被覆盖,原签名apk用新签名后,可替换原签名。
- 使用zipalign先对齐需要签名的apk(具体命令见链接)通过
apksigner
使用私钥进行签名(具体命令见链接)验证apk是否签名(具体命令见链接)相关文章
- H3C路由器带宽保证(命令行)配置方法_优质网络系统领域创作者
- 一阶高通滤波器学习_浅谈电机控制
- 概述.runoob.html_furiyo
- Electron + vite + vue3简单实现_凡小多
- 第48章 SQL FIRST() 函数教程_榴莲酱csdn
- C规范编辑笔记(十)_OMGMac
- Linux常用指令及Web程序的部署_~小明学编程
- scala变量_CarveStone
- Linux应用基础??控制服务与守护进程_PICACHU+++
- Element Plus 跟踪表格数据总数,包括查询、筛选等操作_ymzhaoUSTB
- 分享103个PHP源码,总有一款适合您_MonkT
- [linux] SFTP文件传输基本命令_(∩???????????∩)
- 多核缓存一致性问题及解决方案MESI协议《深入浅出计算机组成原理》学习笔记 Day 4_jahentao
- C规范编辑笔记(十一)_OMGMac
- DW 2023年1月Free Excel 第五次打卡 文本函数_LucyFang2020
- 初识 Bootstrap(前端开发框架)_两个月亮