Gradle transformClassesWithDexForDebug 构建缓慢
Gradle build slow on transformClassesWithDexForDebug
构建我的 Android 应用大约需要 90 秒 ("fast"),每次更新我的代码最多需要 3 分钟。这完全是浪费时间,我认为解决方案一定是触手可及的。我试着调查这个问题,发现了不同的博客文章和带有建议的 SO 答案,其中大部分我都试过了。
- 我有 gradle.properties 文件 org.gradle.deamon=true
- 我 运行 在 Android 工作室 Gradle 喜欢离线工作(改进,但仍然很慢)
- 我在命令行上 运行(更快,但仍然很慢)
- 在 build.gradle 的 defaultConfig 中,我将 multiDexEnabled 设置为 false
- 在 build.gradle、dexOptions 中,我将 preDexLibraries 设置为 false
- 在 gradle-wrapper.properties 中,我获取了最近的 gradle 版本 (2.8)(显着的速度变化发生在 2.4 上)
这个过程似乎很长,大约占总构建时间的 85% :app:transformClassesWithDexForDebug
该进程实际上在做什么?我可以找到遇到崩溃的人,但它对我来说很好用,除了它需要很多时间。我需要它吗,因为此时我真的不需要 Dex?
此外,我有 13 个依赖项和 3 个 testCompile 依赖项。我已经指出了特定的播放包,所以我不会编译我不需要的东西。如果我理解正确,gradle 也在构建每个项目构建的所有这些库。如果那是正确的,有没有办法跳过它?我可以自己将它们构建为包装库并包含它们而不需要每次都处理它们吗?这可能会让我失去一些未来更改依赖项的灵活性,但在这一点上,我觉得我每天很容易在等待 gradle 上浪费一个多小时。我不确定灵活性对我来说是否值得。
我期待获得有关如何改进构建过程的任何指示。提前谢谢你。
这似乎是 Android Studio 2.0 预览版中引入的新 Instant 运行 机制的一部分,该机制负责检测应用中的每个方法,为未来的代码补丁创建执行分支。恐怕这就是它非常慢的原因。
奇怪的是,即使 Instant 运行 已禁用,该任务仍在进行。我必须将 "com.android.tools.build:gradle" 降级到 1.3.0 才能避免该任务。
我遇到了同样的问题,我花了大约 10 个小时才最终解决它,所以我知道你的感受。
我在谷歌上搜索了很多,我做了和你一样的配置,即使它有一点帮助,编译和 运行 实际的应用程序仍然很痛苦(有时需要 2-我更改一行代码需要 3 分钟,但当我做更多的工作时,通常需要 8 分钟,并且在那段时间我的电脑完全死机了)。
但是谈够了,让我们解决这个问题。 'app:transformClassesWithDexForDebug' 所做的是它解决了 Dalvik(5.0 之前,api 21)OS 版本的一些依赖关系,重要的是 - 这需要很多时间。你不需要它来开发,因为你可以在 >= 21 上测试你的应用程序,所以为开发和发布创建单独的产品风格。这是我使用它的 gradle 构建:
apply plugin: 'com.android.application'
final VERSION_MAJOR = 0
final VERSION_MINOR = 0
final VERSION_PATCH = 0
final VERSION_BUILD = 1
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.app"
minSdkVersion 15
targetSdkVersion 23
multiDexEnabled true
versionName "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILD}"
versionCode VERSION_MAJOR * 10000000 + VERSION_MINOR * 100000 + VERSION_PATCH * 1000 + VERSION_BUILD
}
dexOptions {
incremental = true;
preDexLibraries = false
javaMaxHeapSize "2g"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
dev {
minSdkVersion 21
applicationId = "com.app.test"
}
prod {
minSdkVersion 15
applicationId = "com.app" // you don't need it, but can be useful
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
exclude 'META-INF/ASL2.0'
}
lintOptions {
checkReleaseBuilds false
abortOnError true
}
}
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = ['--multi-dex']
} else {
dx.additionalParameters += '--multi-dex'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
...
}
接下来要确保您确实使用此 build variant 构建您的应用程序。点击 View -> Tool Windows -> Build tools 并确保你已将构建变体设置为 'devDebug'
对于某些人来说,这可能就足够了。我在 SO 和 reddit 上发现了很多以这种产品风味结尾的话题,但这实际上对我没有任何帮助。对我有帮助的是手动升级 gradle。既然你已经尝试过这样做,我认为你走在正确的轨道上,但我建议使用更新的 gradle 版本 2.9,它的 '40% improved performance' 超过 2.8.
编辑:在这一点上,我推荐 运行ning Android Studio 2.x 与 1.5 并排安装。您可以访问 instant-运行,它和所有更新的工具一样非常有用。如果您继续使用 1.5,请继续阅读...
我已经设法将 Android Studio 1.5 调试构建从 2 分钟缩短到 30 秒。这可能不适用于您的命令行执行,但可能会更快。
使用此配置,您的第一个 IDE 构建需要 相同的时间,但增量构建更快,即使你修改 类。如果您修改附加库,您会失去一些收益。
第 1 步。(如果您足够幸运,目标 minSdkVersion 已经 >= 21,请跳过此步骤。)
@vanomart 的 minSdkVersion 调试风格 >= 21 的回答并没有错,但唯一需要的部分是将以下内容添加到 module (app) build.gradle 并确保在 Build Variants 选项卡中调试时以 dev 为目标:
android {
[...]
productFlavors {
dev {
minSdkVersion 21 //The important bit.
}
prod {
minSdkVersion 15 //Example. Set to your real requirement.
}
}
步骤 2。 预索引库。
在您的 模块(应用程序)中 build.gradle 设置以下配置。这对于 IDE 构建来说速度更快,对于每次构建都从头开始的构建器服务器来说不是那么快。
android {
[...]
dexOptions {
preDexLibraries true
javaMaxHeapSize "2g" // Use gig increments depending on needs
}
来源,做(部分)“提高构建服务器性能”的逆操作:
http://tools.android.com/tech-docs/new-build-system/tips#TOC-Improving-Build-Server-performance
步骤 3. 确保您在 模块(应用程序)build.gradle.[=20 中使用最新的 buildToolsVersion =]
android {
buildToolsVersion "23.0.2"
[...]
"... update the build tools version in all your modules to the latest
(23.0.2). [...] it will use a new faster version of dex, which helps
both instant run and a full build be a bit faster."
来源:http://tools.android.com/tech-docs/instant-run
步骤 4. 使用最新的 Gradle 构建工具
在您的项目build.gradle中,设置为最新(当前为 2.0.0-alpha6)
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-alpha6'
更新列表:http://tools.android.com/tech-docs/new-build-system
步骤 5. 使用最新的 Gradle 包装器。修改gradle-wrapper.properties,更新这一行使用2.10:
distributionUrl=https\://downloads.gradle.org/distributions/gradle-2.10-all.zip
#Alternative url if the above does not work:
#distributionUrl=https://services.gradle.org/distributions/gradle-2.10-all.zip
在 Android Studio 首选项中,确保选择了“使用默认 Gradle 包装器”。我建议重新启动 Android Studio 以确保 Gradle 守护程序重新启动。
"In many cases, Gradle 2.9 is much faster than Gradle 2.8 when
performing incremental builds."
来源:docs.gradle.org/current/release-notes
你的应用程序有数据库吗?数据库大吗?
如果是:
- 从资产文件夹(或任何保存它的地方)中删除数据库并进行构建
- 衡量构建时间的差异
- 在我的案例中:从 45 秒到 15 秒有很大的不同
如果否:
- 在增量构建期间监视 Gradle 控制台,看看哪个操作花费的时间最多
唯一对我有用的解决方案是禁用即时 运行。
Android Studio -> 首选项 -> 构建、执行、部署 -> 即时 运行 -> 取消选中 'Enable instant run [...]'
构建时间从 2 多分钟缩短到 40 秒。
升级到 Android Studio 2.1 和 Android Gradle 插件 v2.1.0 已经为我解决了这个问题。安装更新的 IDE 后,系统会提示您也更新 Gradle 插件。如果您的根 build.gradle 文件包含以下行,您将知道您拥有正确的版本:
classpath 'com.android.tools.build:gradle:2.1.0'
重要提示:除了升级之外,您还需要将分配给 Gradle 守护程序的内存量增加到 2048mb,以便它可以在过程中执行这个昂贵的 dex-ing 步骤。为此,请将以下内容添加到根 gradle.properties 文件中:
org.gradle.jvmargs = -Xmx2048m
我在上述问题中遇到的构建时间同样缓慢,但升级后我的构建速度显着提高。有关详细信息,请参阅此处 Android Gradle 插件 v2.1.0 的发行说明:
http://developer.android.com/tools/revisions/gradle-plugin.html
构建我的 Android 应用大约需要 90 秒 ("fast"),每次更新我的代码最多需要 3 分钟。这完全是浪费时间,我认为解决方案一定是触手可及的。我试着调查这个问题,发现了不同的博客文章和带有建议的 SO 答案,其中大部分我都试过了。
- 我有 gradle.properties 文件 org.gradle.deamon=true
- 我 运行 在 Android 工作室 Gradle 喜欢离线工作(改进,但仍然很慢)
- 我在命令行上 运行(更快,但仍然很慢)
- 在 build.gradle 的 defaultConfig 中,我将 multiDexEnabled 设置为 false
- 在 build.gradle、dexOptions 中,我将 preDexLibraries 设置为 false
- 在 gradle-wrapper.properties 中,我获取了最近的 gradle 版本 (2.8)(显着的速度变化发生在 2.4 上)
这个过程似乎很长,大约占总构建时间的 85% :app:transformClassesWithDexForDebug
该进程实际上在做什么?我可以找到遇到崩溃的人,但它对我来说很好用,除了它需要很多时间。我需要它吗,因为此时我真的不需要 Dex?
此外,我有 13 个依赖项和 3 个 testCompile 依赖项。我已经指出了特定的播放包,所以我不会编译我不需要的东西。如果我理解正确,gradle 也在构建每个项目构建的所有这些库。如果那是正确的,有没有办法跳过它?我可以自己将它们构建为包装库并包含它们而不需要每次都处理它们吗?这可能会让我失去一些未来更改依赖项的灵活性,但在这一点上,我觉得我每天很容易在等待 gradle 上浪费一个多小时。我不确定灵活性对我来说是否值得。
我期待获得有关如何改进构建过程的任何指示。提前谢谢你。
这似乎是 Android Studio 2.0 预览版中引入的新 Instant 运行 机制的一部分,该机制负责检测应用中的每个方法,为未来的代码补丁创建执行分支。恐怕这就是它非常慢的原因。
奇怪的是,即使 Instant 运行 已禁用,该任务仍在进行。我必须将 "com.android.tools.build:gradle" 降级到 1.3.0 才能避免该任务。
我遇到了同样的问题,我花了大约 10 个小时才最终解决它,所以我知道你的感受。
我在谷歌上搜索了很多,我做了和你一样的配置,即使它有一点帮助,编译和 运行 实际的应用程序仍然很痛苦(有时需要 2-我更改一行代码需要 3 分钟,但当我做更多的工作时,通常需要 8 分钟,并且在那段时间我的电脑完全死机了)。
但是谈够了,让我们解决这个问题。 'app:transformClassesWithDexForDebug' 所做的是它解决了 Dalvik(5.0 之前,api 21)OS 版本的一些依赖关系,重要的是 - 这需要很多时间。你不需要它来开发,因为你可以在 >= 21 上测试你的应用程序,所以为开发和发布创建单独的产品风格。这是我使用它的 gradle 构建:
apply plugin: 'com.android.application'
final VERSION_MAJOR = 0
final VERSION_MINOR = 0
final VERSION_PATCH = 0
final VERSION_BUILD = 1
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.app"
minSdkVersion 15
targetSdkVersion 23
multiDexEnabled true
versionName "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILD}"
versionCode VERSION_MAJOR * 10000000 + VERSION_MINOR * 100000 + VERSION_PATCH * 1000 + VERSION_BUILD
}
dexOptions {
incremental = true;
preDexLibraries = false
javaMaxHeapSize "2g"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
dev {
minSdkVersion 21
applicationId = "com.app.test"
}
prod {
minSdkVersion 15
applicationId = "com.app" // you don't need it, but can be useful
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
exclude 'META-INF/ASL2.0'
}
lintOptions {
checkReleaseBuilds false
abortOnError true
}
}
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = ['--multi-dex']
} else {
dx.additionalParameters += '--multi-dex'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
...
}
接下来要确保您确实使用此 build variant 构建您的应用程序。点击 View -> Tool Windows -> Build tools 并确保你已将构建变体设置为 'devDebug'
对于某些人来说,这可能就足够了。我在 SO 和 reddit 上发现了很多以这种产品风味结尾的话题,但这实际上对我没有任何帮助。对我有帮助的是手动升级 gradle。既然你已经尝试过这样做,我认为你走在正确的轨道上,但我建议使用更新的 gradle 版本 2.9,它的 '40% improved performance' 超过 2.8.
编辑:在这一点上,我推荐 运行ning Android Studio 2.x 与 1.5 并排安装。您可以访问 instant-运行,它和所有更新的工具一样非常有用。如果您继续使用 1.5,请继续阅读...
我已经设法将 Android Studio 1.5 调试构建从 2 分钟缩短到 30 秒。这可能不适用于您的命令行执行,但可能会更快。
使用此配置,您的第一个 IDE 构建需要 相同的时间,但增量构建更快,即使你修改 类。如果您修改附加库,您会失去一些收益。
第 1 步。(如果您足够幸运,目标 minSdkVersion 已经 >= 21,请跳过此步骤。)
@vanomart 的 minSdkVersion 调试风格 >= 21 的回答并没有错,但唯一需要的部分是将以下内容添加到 module (app) build.gradle 并确保在 Build Variants 选项卡中调试时以 dev 为目标:
android {
[...]
productFlavors {
dev {
minSdkVersion 21 //The important bit.
}
prod {
minSdkVersion 15 //Example. Set to your real requirement.
}
}
步骤 2。 预索引库。
在您的 模块(应用程序)中 build.gradle 设置以下配置。这对于 IDE 构建来说速度更快,对于每次构建都从头开始的构建器服务器来说不是那么快。
android {
[...]
dexOptions {
preDexLibraries true
javaMaxHeapSize "2g" // Use gig increments depending on needs
}
来源,做(部分)“提高构建服务器性能”的逆操作: http://tools.android.com/tech-docs/new-build-system/tips#TOC-Improving-Build-Server-performance
步骤 3. 确保您在 模块(应用程序)build.gradle.[=20 中使用最新的 buildToolsVersion =]
android {
buildToolsVersion "23.0.2"
[...]
"... update the build tools version in all your modules to the latest (23.0.2). [...] it will use a new faster version of dex, which helps both instant run and a full build be a bit faster."
来源:http://tools.android.com/tech-docs/instant-run
步骤 4. 使用最新的 Gradle 构建工具
在您的项目build.gradle中,设置为最新(当前为 2.0.0-alpha6)
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-alpha6'
更新列表:http://tools.android.com/tech-docs/new-build-system
步骤 5. 使用最新的 Gradle 包装器。修改gradle-wrapper.properties,更新这一行使用2.10:
distributionUrl=https\://downloads.gradle.org/distributions/gradle-2.10-all.zip
#Alternative url if the above does not work:
#distributionUrl=https://services.gradle.org/distributions/gradle-2.10-all.zip
在 Android Studio 首选项中,确保选择了“使用默认 Gradle 包装器”。我建议重新启动 Android Studio 以确保 Gradle 守护程序重新启动。
"In many cases, Gradle 2.9 is much faster than Gradle 2.8 when performing incremental builds."
来源:docs.gradle.org/current/release-notes
你的应用程序有数据库吗?数据库大吗?
如果是:
- 从资产文件夹(或任何保存它的地方)中删除数据库并进行构建
- 衡量构建时间的差异
- 在我的案例中:从 45 秒到 15 秒有很大的不同
如果否:
- 在增量构建期间监视 Gradle 控制台,看看哪个操作花费的时间最多
唯一对我有用的解决方案是禁用即时 运行。
Android Studio -> 首选项 -> 构建、执行、部署 -> 即时 运行 -> 取消选中 'Enable instant run [...]'
构建时间从 2 多分钟缩短到 40 秒。
升级到 Android Studio 2.1 和 Android Gradle 插件 v2.1.0 已经为我解决了这个问题。安装更新的 IDE 后,系统会提示您也更新 Gradle 插件。如果您的根 build.gradle 文件包含以下行,您将知道您拥有正确的版本:
classpath 'com.android.tools.build:gradle:2.1.0'
重要提示:除了升级之外,您还需要将分配给 Gradle 守护程序的内存量增加到 2048mb,以便它可以在过程中执行这个昂贵的 dex-ing 步骤。为此,请将以下内容添加到根 gradle.properties 文件中:
org.gradle.jvmargs = -Xmx2048m
我在上述问题中遇到的构建时间同样缓慢,但升级后我的构建速度显着提高。有关详细信息,请参阅此处 Android Gradle 插件 v2.1.0 的发行说明:
http://developer.android.com/tools/revisions/gradle-plugin.html