简单说下一个 apk 的组成有哪些部分?
一个 APK 文件(Android 应用程序包)主要由以下几个部分组成:
- AndroidManifest.xml:这是 APK 的核心文件,包含了应用的基本配置信息,如应用的权限声明、组件(Activity、Service、BroadcastReceiver、ContentProvider)的声明、应用的入口等。
- classes.dex:包含了应用的编译代码。DEX(Dalvik Executable)文件格式是 Android 程序的字节码格式,Android 系统会加载这些字节码文件来运行应用。
- resources.arsc:包含了应用的所有资源的索引(例如字符串、颜色、样式等)。这个文件是一个二进制文件,包含了资源文件的访问路径和对应的资源值。
- res/ :该文件夹包含了应用的所有资源文件,如布局文件(XML)、图片文件(PNG、JPEG 等)、动画文件、音频文件等。
- assets/ :存放应用中的原始文件,通常这些文件是没有经过修改的,可以是任何类型的文件。与
res/
文件夹不同,assets/
中的文件不会被 Android 系统处理,而是作为原始数据提供给应用使用。 - META-INF/ :这个文件夹包含了 APK 的元数据,例如签名证书(.RSA 文件)和其他相关信息。它确保应用包没有被篡改,并且可以确认应用的发布者。
- lib/ :包含了应用使用的本地库(如
.so
文件)。这些文件通常是为特定平台架构(如 ARM、x86)编译的本地代码,Android 会根据设备架构选择合适的库来加载。
这些部分共同组成了一个完整的 APK 文件,确保应用能够在 Android 设备上正确安装和运行。
简单说下 Apk 构建的过程,这些过程分别用到了哪些工具?
-
代码编译:
- 工具:Javac / Kotlin Compiler
- 开发者编写的 Java 或 Kotlin 代码会被编译成字节码(
.class
文件),然后通过dx
或D8
工具转化为.dex
文件(Dalvik Executable),使得代码可以在 Android 设备上运行。
-
资源编译:
- 工具:aapt (Android Asset Packaging Tool)
aapt
工具将res/
文件夹中的资源(如布局、字符串、图片)编译为二进制格式并打包到resources.arsc
文件中。这些资源文件会被 APK 打包时使用。
-
生成 AndroidManifest.xml 文件:
- 工具:aapt
- 在构建过程中,
AndroidManifest.xml
文件中的配置信息会被验证、处理并包含到 APK 中。
-
打包和签名:
- 工具:apktool、jarsigner、zipalign
- APK 文件的最终打包过程包括将
.dex
文件、资源文件、库文件以及AndroidManifest.xml
合并成一个.apk
文件。 - 需要使用
jarsigner
工具对 APK 进行签名,确保应用的安全性和完整性。 - 使用
zipalign
工具对 APK 进行优化,确保它能够更高效地在设备上运行。
-
调试和优化:
- 工具:ProGuard / R8
- 在发布之前,开发者可能会使用
ProGuard
或R8
工具对代码进行混淆和优化,以减小 APK 大小并提高应用的安全性。
-
生成 APK:
- 最后,构建工具(如 Gradle)会将所有文件打包成一个 APK 文件,准备好进行发布或安装。
简单说下 aapt 和 aapt2 之间有什么不同?
-
aapt:不支持增量编译,每次构建都会重新处理所有资源文件。
-
aapt2:支持增量编译,仅在资源文件发生变化时才进行处理,这使得构建过程更加高效。
aapt2
是对 aapt
的改进,具备了更高的性能、更好的错误处理、更高效的增量构建和更强的稳定性,推荐在现代 Android 开发中使用 aapt2
。
手动打包一个可以运行的 apk,让这个 apk 体积尽可能小
步骤 2:编译和生成 .dex
文件
-
编译源代码 : 使用
javac
(或者如果使用 Kotlin 的话使用kotlinc
)编译源代码文件:jsjavac -d out/ src/com/example/myapp/MainActivity.java
-
将
.class
文件转为.dex
文件 : 使用dx
或d8
工具将.class
文件转为.dex
格式:jsdx --dex --output=out/classes.dex out/
步骤 3:编译资源文件
-
处理资源文件 : 使用
aapt2
来编译res/
文件夹中的资源:jsaapt2 compile res/ -o out/
-
打包资源文件 : 使用
aapt2
将资源文件和.dex
文件打包成 APK:jsaapt2 link -o out/myapp.apk --manifest AndroidManifest.xml -I /path/to/android.jar out/*.flat
步骤 4:签名 APK
-
生成签名证书 : 使用
keytool
生成一个新的签名证书:jskeytool -genkeypair -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key
-
使用
jarsigner
签名 APK : 使用jarsigner
对 APK 进行签名:jsjarsigner -verbose -sigalg SHA1withRSA -digestalg SHA-1 -keystore my-release-key.jks out/myapp.apk my-key
步骤 5:优化 APK 体积
-
去除未使用的资源:
- 使用
ProGuard
或R8
进行代码混淆和优化,去除未使用的类和资源,从而减小 APK 大小。 - 可以通过 Gradle 配置启用 R8 或 ProGuard,例如在
build.gradle
文件中启用混淆:
jsandroid { buildTypes { release { minifyEnabled true // 启用代码压缩 shrinkResources true // 去除未使用的资源 } } }
- 使用
-
使用
zipalign
优化 APK 文件 : 使用zipalign
工具优化 APK 文件,使得它在设备上加载时更高效:jszipalign -v 4 out/myapp.apk out/myapp-aligned.apk
步骤 6:最终 APK
现在,APK 文件已经构建完成,并且尽可能小。你可以使用 adb install
命令将它安装到设备上:
js
adb install out/myapp-aligned.apk
小结
- 在手动打包 APK 时,关键的步骤包括编译源代码、处理资源、签名和优化。
- 为了减小 APK 的体积,最重要的是去除未使用的资源和代码,使用混淆工具(如 ProGuard 或 R8)来进一步压缩。
- 使用
zipalign
可以优化 APK 体积和运行效率。