添加新库后,Android Studio构建速度变慢了?

17

我的应用程序使用旧的架构组件。我想转移到新的 android架构组件

为此,我在开头添加了与room相关的依赖项,之后构建是正常的。

但是,当我尝试添加生命周期、LiveData和ViewModel的依赖项时,如这里所述。

应用程序构建过程显著减慢,需要5分钟甚至更长时间来构建apk。

在应用程序的build.gradle中添加了以下依赖项:

    compile "android.arch.lifecycle:runtime:1.0.0-alpha5"
    compile "android.arch.lifecycle:extensions:1.0.0-alpha5"
    annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha5"

此外,我需要启用jack以实现Java 8兼容性,如下所示:

defaultConfig {
........
        jackOptions {
            enabled true
        }
    }

在添加了所有这些组件之后,构建过程明显变慢了。我尝试通过转到帮助 -> 编辑自定义VM选项来更改一些参数的自定义VM选项。

-Xmx5120m

我将其设置为接近5GB,但对我没有任何作用。 我相信我的机器有足够的硬件(8GB RAM,Windows 10,1TB HDD,AMD A8)。
我的应用程序使用了许多Google服务,例如Gmail API,Firebase API,一些其他库,我是否已经超出了64K参考限制? 但是,如此处所述,我已经启用了multidexing。
这是由于新的架构组件或其他原因引起的吗? 如何使构建过程更快?
更新:
下面Budius的一个答案建议使用脚本显示每个构建过程所需的时间,我在我的应用程序中执行了它,以下是结果:
BUILD SUCCESSFUL

Total time: 18 mins 28.44 secs
Task timings:
    480ms  :app:mergeDebugResources
   2516ms  :app:processDebugResources
 487725ms  :app:transformClassesWithPreJackPackagedLibrariesForDebug
  29213ms  :app:transformClassesWithPreJackRuntimeLibrariesForDebug
    752ms  :app:transformResourcesWithMergeJavaResForDebug
 556894ms  :app:transformJackWithJackForDebug
   5184ms  :app:transformNativeLibsWithMergeJniLibsForDebug
  17524ms  :app:packageDebug

大多数时间由Jack记录。

我尝试了Bryan在下面答案中建议的canary版本,以下是构建过程所需时间的输出:

BUILD SUCCESSFUL in 6m 11s
42 actionable tasks: 33 executed, 9 up-to-date
Task timings:
    608ms  :app:preDebugBuild
    350ms  :app:mergeDebugResources
    394ms  :app:processDebugManifest
   2543ms  :app:processDebugResources
   9410ms  :app:javaPreCompileDebug
  46585ms  :app:compileDebugJavaWithJavac
    262ms  :app:compileDebugShaders
    395ms  :app:mergeDebugAssets
   5835ms  :app:packageInstantRunResourcesDebug
  98922ms  :app:transformClassesWithDesugarForDebug
    334ms  :app:transformClassesWithExtractJarsForDebug
   7765ms  :app:transformClassesWithInstantRunVerifierForDebug
  23117ms  :app:transformNativeLibsWithMergeJniLibsForDebug
  10128ms  :app:transformResourcesWithMergeJavaResForDebug
  16565ms  :app:transformClassesWithInstantRunForDebug
  11825ms  :app:transformClassesWithInstantRunSlicerForDebug
  84703ms  :app:transformClassesWithDexBuilderForDebug
  17061ms  :app:transformDexArchiveWithDexMergerForDebug
   1706ms  :app:transformDexWithInstantRunDependenciesApkForDebug
   9770ms  :app:transformDexWithInstantRunSlicesApkForDebug
  10571ms  :app:packageDebug
   1387ms  :app:buildInfoGeneratorDebug

所以我移除了jack并切换到这个canary版本,构建速度肯定比之前快,但对于使用来说仍然很慢。


1
这显然会减慢进程,但5分钟太长了,因为它进行编译时注释处理,并在编译阶段创建新的类文件并添加支持双向数据绑定..你能否使用命令共享gradle日志... gradlew build > myLogs.txt..我只想看看你实现了多少双向绑定内容,或者是因为其他原因导致的..如果可能的话,请分享您的应用程序级别gradle,但请隐藏signingConfigs keyAlias和密码 :) - Anukalp Katyal
为了测量构建时间,您可以运行“./gradlew assembleDebug --scan”,然后转到https://scans.gradle.com。 - Evgenii Vorobei
7个回答

8
很多关于你的问题的假设都是基于这个或那个可能性,即存在“很多”的情况。但是时间是一件非常容易测量的事情,gradle将构建过程分成几个较小的任务。因此,我认为你最好的行动是测量每个任务,然后你就可以比较哪些任务花费了很长时间。
这里有一个脚本我制作的用于测量构建时间,只需将其添加到项目的根文件夹中,并在顶层gradle文件中添加apply from: 'time.gradle' timer.gradle
import java.util.concurrent.TimeUnit

class TimingsListener implements TaskExecutionListener, BuildListener {
    private long startTime
    private timings = []

    @Override
    void beforeExecute(Task task) {
        startTime = System.nanoTime()
    }

    @Override
    void afterExecute(Task task, TaskState taskState) {
        def ms = TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
        timings.add([ms, task.path])
    }

    @Override
    void buildFinished(BuildResult result) {
        println "Task timings:"
        for (timing in timings) {
            if (timing[0] >= 250) {
                printf "%7sms  %s\n", timing
            }
        }
    }

    @Override
    void buildStarted(Gradle gradle) {}

    @Override
    void projectsEvaluated(Gradle gradle) {}

    @Override
    void projectsLoaded(Gradle gradle) {}

    @Override
    void settingsEvaluated(Settings settings) {}
}

gradle.addListener new TimingsListener()

这是一个好建议,我会查看构建过程中每个子任务所需的时间,然后可能会更新我的问题,谢谢。 - Prashant
我建议使用 ./gradlew --profile <taskname> 命令,它会生成一个包含时间分解的 HTML 文件。通常这些文件会在 ./build/reports/profile 目录下。 - Fabio
我将文件timer.gradle复制到我的项目根目录中,然后在顶层build.gradle中添加了一行'apply from time.gradle'。但是我遇到了以下错误:Error:(26, 0) Could not get unknown property 'from' for root project 'MyApp' of type org.gradle.api.Project. - Prashant
@pcj编辑了我的答案,它错过了这个符号:。它必须是apply from: 'timer.gradle' - Budius
@pcj 我已经检查了你的结果,似乎大部分时间都是与Jack相关的操作,所以我的建议是禁用/删除Jack编译器。正如Bryan的答案中提到的,它已经被弃用,不应该再使用。因此:删除Jack,并确保你正在运行最新版本的Gradle和Gradle Android插件。然后再次检查计时器。 - Budius

6

Jack工具链已经弃用,并且在被弃用之前仍处于实验阶段。尽管生成代码的过程可能会很慢(如@ FlorescuGeorgeCătălin所述),但通常不会导致构建时间如此缓慢。我怀疑你的构建时间缓慢的原因是Jack工具链;因为 以慢著称 特别是 缓慢

如果您想使用Java 8语言功能,我建议您转移到Android Studio 3.0的预览版本,该版本已内置这些功能

如果那不是一个选项,你可以使用Retrolambda,它包含大部分Java 8语言特性。

嘿,感谢您的建议。我已经更新了我的问题,到目前为止,您提供的解决方案对我有效。 - Prashant

2

由于该库具有注解处理器,因此必须将新代码生成到生成的类中。Dagger也是一个生成代码的库。Butterknife也是如此。

你可以在项目文件夹app/build/generated中找到它们。

你可以在这里了解更多关于注解处理器的内容。

也可以从你的硬盘驱动器中获取。使用SSD硬盘驱动器可以提供更强大的处理能力。


1

你是否将Gradle设置为离线工作,并尝试编辑自定义VM选项以增加堆大小?

另一个解决方案是升级Android Studio到Android Studio 3.0,这也可以提高构建速度。


1

文件 -> 设置 -> (左侧) 构建、执行、开发 -> 构建工具 -> Gradle

在“全局Gradle设置”下,会有一个名为“离线工作”的复选框。请勾选它。

你完成了吗?


1
请在 build.gradle 文件中的 android {} 中添加以下内容。
dexOptions {
    incremental true
    javaMaxHeapSize "4g"
}

在gradle.properties文件中设置以下内容:
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
android.enableBuildCache=true
org.gradle.caching=true

0
这可能有点冒险,但是你的测试机器上是否连接了真正的安卓设备?我注意到如果我的测试设备连接着,我的AS运行得非常缓慢,也许adb出了问题,从而导致系统变慢。
另外,我将我的旧机器升级到了16GB内存i7处理器,事情开始运行得更快了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接