AndroidStudio 点击 build 按钮后,AndroidStudio 就会编译整个项目,并将 apk 安装到手机上,这个过程就是 Android 工程编译打包过程。主要的流程是
- 编译
- DEX
- 打包
- 签名
APK 构建概述
下图是谷歌官方给出的一个典型的 APK 构建过程。
主要有两个过程:
- 编译过程
- 输入是本工程的文件以及依赖的各种库文件
- 输出是 dex 文件和编译后的资源文件
- 打包过程
- 配合 Keystore 对上述的输出进行签名对齐,生成最终的 apk 文件。
APK 构建步骤详解
Android APK 构建的详细步骤如下图所示。
- 打包资源文件,生成 R.java 文件
- 输入:
- Resource 文件(即工程 res 中的文件)
- Assets 文件(即工程 assets 中的文件)
- AndroidMainfest.xml 文件
- Android 基本类库(Android.jar 文件)
- 输入:
- R.java 文件(在 model 工程的 build/generated 目录)
- 打包好的资源
- 工具:appt 工具
- 输入:
- 处理 AIDL 文件 (没有可以省略),生成对应的 .java 文件
- 输入:源码文件、aidl 文件、framework.aidl 文件
- 输出:对应的 .java 文件
- 工具:aidl 工具
- 编译 Java 文件,生成对应的 .class 文件
- 输入:
- 源码文件(包括第 1 步的 R.java 和第 2 步 AIDL 生成的 .java 文件)
- 库文件(.jar 文件)
- 输出:对应的 .class 文件
- 工具:javac 工具
- 输入:
- 把 .class 文件转化成 Davik VM 支持的 .dex 文件
- 输入:
- 第 3 步生成的 .class 文件(包括 AIDL、R.java、源代码生成的 .class 文件)
- 库文件(.jar 文件)
- 输出:对应的 .dex 文件
- 工具:javac 工具
- 输入:
- 打包生成为签名的 .apk 文件
- 输入:
- 打包后的资源文件(包括本地和第三方库里的)
- 打包后的 .dex 文件
- libs 文件(包括 .so 文件,如果涉及 C/C++ 开发的话)
- 输出:未签名的 .apk 文件
- 工具:apkbuilder 工具
- 输入:
- 对未签名 .apk 文件进行签名
- 输入:未签名的 .apk 文件
- 输出:签名的 .apk 文件
- 工具:jarsigner 工具
- 对签名后 .apk 文件进行对齐处理
- 输入:签名的 .apk 文件
- 输出:对齐后的 .apk 文件
- 工具:zipalign 工具
其他
整个过程可以通过命令行
./gradlew assembleRelease --info
执行的 Task 看到。123456789101112131415161718192021222324252627282930313233Tasks to be executed: [task ':app:preBuild',task ':app:preReleaseBuild',task ':app:compileReleaseAidl',task ':app:compileReleaseRenderscript',task ':app:checkReleaseManifest',task ':app:generateReleaseBuildConfig',task ':app:prepareLintJar',task ':app:generateReleaseResValues',task ':app:generateReleaseResources',task ':app:mergeReleaseResources',task ':app:createReleaseCompatibleScreenManifests',task ':app:processReleaseManifest',task ':app:splitsDiscoveryTaskRelease',task ':app:processReleaseResources',task ':app:generateReleaseSources',task ':app:javaPreCompileRelease',task ':app:compileReleaseJavaWithJavac',task ':app:compileReleaseNdk',task ':app:compileReleaseSources',task ':app:mergeReleaseShaders',task ':app:compileReleaseShaders',task ':app:generateReleaseAssets',task ':app:mergeReleaseAssets',task ':app:transformClassesWithPreDexForRelease',task ':app:transformDexWithDexForRelease',task ':app:mergeReleaseJniLibFolders',task ':app:transformNativeLibsWithMergeJniLibsForRelease',task ':app:transformNativeLibsWithStripDebugSymbolForRelease',task ':app:processReleaseJavaRes',task ':app:transformResourcesWithMergeJavaResForRelease',task ':app:packageRelease',task ':app:lintVitalRelease',task ':app:assembleRelease']通过反编译 APK 文件,可以间接看到打包流程和 APK 的组成文件
- 反编译主要过程
- 将 apk 解压(可以变成 zip 压缩文件在解压)
- 找到 class.dex 文件,用 dex2jar 工具,将 dex 文件转成 jar 文件,命令 d2j-dex2jar classes.dex
- 用 jd-gui 工具,将 jar 文件转换成 Java 代码
- 用 apktool 这个工具用于最大幅度地还原 APK 文件中的 9-patch 图片、布局、字符串等等一系列的资源。命令 apktool d xxx.apk
- 反编译主要过程