简世博客

一个简单的世界——博客空间,写了一些Android相关的技术文章,和一些点滴的想法

0%

android studio编译和命令行调用gradle编译的区别

android studio编译比命令行调用gradle编译快很多

从Android Studio 2.3版本之后,通过Android Studio打包普遍比通过命令行调用gradle编译要快很多。这是因为Android Studio增加了一项功能。通过Android Studio打包是,检测到连接的手机android本部大于21,就会关闭传统multidex方案,而使用速度快得多的新版多dex打包流程。

google原文如下:
https://developer.android.com/studio/build/optimize-your-build

1
2
3
4
// To avoid using legacy multidex when building from the command line,
// set minSdkVersion to 21 or higher. When using Android Studio 2.3 or higher,
// the build automatically avoids legacy multidex when deploying to a device running
// API level 21 or higher—regardless of what you set as your minSdkVersion.

传统multidex和新版多dex打包区别

传统multidex打包流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
app:kaptGenerateStubsDevDebugKotlin
app:kaptDevDebugKotlin
app:compileDevDebugKotlin
app:javaPreCompileDevDebug
app:compileDevDebugJavaWithJavac
app:compileDevDebugSources
app:transformClassesWithStackFramesFixerForDevDebug
app:transformClassesWithDesugarForDevDebug
app:transformClassesWithDexBuilderForDevDebug
app:transformClassesWithMultidexlistForDevDebug
app:transformDexArchiveWithDexMergerForDevDebug
app:transformNativeLibsWithMergeJniLibsForDevDebug
app:transformResourcesWithMergeJavaResForDevDebug
app:packageDevDebug
app:assembleDevDebug

新版多dex打包流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
:app:kaptGenerateStubsDevDebugKotlin
:app:kaptDevDebugKotlin
:app:compileDevDebugKotlin
:app:generateDevDebugSources
:app:javaPreCompileDevDebug
:app:compileDevDebugJavaWithJavac
:app:compileDevDebugSources
:app:transformClassesWithStackFramesFixerForDevDebug
:app:transformClassesWithDesugarForDevDebug
:app:transformClassesWithDexBuilderForDevDebug
:app:transformDexArchiveWithDexMergerForDevDebug
:app:transformNativeLibsWithMergeJniLibsForDevDebug
:app:transformResourcesWithMergeJavaResForDevDebug
:app:packageDevDebug
:app:assembleDevDebug

可以看出,传统multidex比新版多dex打包,多了一个transformClassesWithMultidexlist的任务,而这个任务耗费时间非常的长。
这就是导致命令行调用gradle命令编译比Android Studio慢的区别。

Android Studio 如何改变了打包流程

Android Studio是通过检测连接手机的参数,来向gradle注入相关属性来修改gradle编译方式。
我们可以在build.gradle中加入如下命令来查看Android Studio注入的属性:

1
println "projectProperties: " + project.gradle.startParameter.projectProperties

project.gradle.startParameter.projectProperties表示当前gradle启动时设置的属性。

我测试发现,注入的属性如下:

1
2
3
4
5
6
projectProperties: [
android.injected.build.density:xxhdpi,
android.injected.build.api:26,
android.injected.invoked.from.ide:true,
android.injected.build.abi:arm64-v8a,armeabi-v7a,armeabi
]

这几个属性:
android.injected.build.density 只打包对应density的资源,
android.injected.build.api 连接手机的android版本,就是这个属性使gradle采用新版多dex打包方案

让命令行调用gradle命令编译和Android Studio一样快

只要在原本的编译命令中加入-Pandroid.injected.build.api=26参数,即可在命令行中也采用新版多dex打包方案

1
./gradlew -Pandroid.injected.build.api=26 assembleDevDebug