【问题标题】:Compiling Android project from command line is slow从命令行编译Android项目很慢
【发布时间】:2012-08-18 18:38:40
【问题描述】:

我正在从 OSX 上的命令行编译我的(相当简单,只有 5 个文件,数百个 LOC)应用程序:

ant debug

它有效。但它运行缓慢:

BUILD SUCCESSFUL Total time:

26 seconds

这是为什么呢?即使我只更改一个 java 文件中的一行,也需要这么多时间。大部分时间都花在dex 阶段(大约 20 秒),这是 AFAIK 创建 Dalvik 字节码。但是我的朋友也在使用 Eclipse 在 Windows 上处理同一个项目,他说在他的机器上编译只需要一两秒钟。我可以做些什么来加快这个过程吗?

【问题讨论】:

  • Apple 与 Android 构建时间有什么关系?顺便说一句,测试 iOS 轻而易举 - 从开始编译到应用在模拟器上运行只需几秒钟。
  • 您说您在 OSX 上运行它,并且您还说您的朋友(在 Windows 上)正在编译同一个项目,而不是(但在 Eclipse 中)......无论如何,您是否尝试过在windows平台上使用ant?如果它比在 Eclipse 中编译比它的蚂蚁问题花费更多的时间如果不是……问题出在你的计算机上。
  • 我没有在 Windows 上尝试过。无论如何,我知道这可能是 ant 的问题,因为它是从头开始重建 dex 文件,而 Eclipse 会缓存它或其他东西。这就是我问这个问题的原因——想知道是否有解决方案。我不想使用 Eclipse,因为它很慢而且我讨厌 UI。

标签: android performance compilation dex


【解决方案1】:

我终于找到了解决方案!这有点小技巧,但它确实有效。

首先,转到您的 ANDROID-SDK/platform-tools 目录,然后将 dx 应用重命名为其他名称,例如 dextool,最后创建包含内容的新 dx 文件:

#!/bin/sh
shift
dextool --dex --incremental --no-optimize $@

将“dextool”替换为您之前选择的名称。这将为每个 dex 调用添加(未记录的)--incremental 属性,这将大量通过仅对在构建之间发生变化的类进行 dex 化来减少构建时间。现在看起来像这样:

[dx] Merged dex A (1 defs/11,3KiB) with dex B (359 defs/1253,2KiB). Result is 359 defs/1519,3KiB. Took 0,5s

0.5s 而不是 20s 差别很大!

编辑 - 几句话:

  • 在使用它之前你必须至少编译一次你的项目,因为它使用了以前的 classes.dex 文件
  • 在使用除 ant 之外的其他 Android 工具链时可能会遇到问题

更新:

Google 发布了 SDK Tools 21.0,它使上述调整被废弃,因为它确实支持 pre-dexing。终于!

【讨论】:

  • 我真希望谷歌能解决这个问题。从 ant 脚本构建需要多长时间有点愚蠢 - 对我来说,使用 ADT 进行清理和重建需要大约 30 秒,而 build.xml ant 脚本需要大约 60 秒。
  • 这实际上非常有效。我已经持续使用它几个星期了,如果你在堆栈跟踪中丢失行号,我能看到的唯一缺点。最好在生产中关闭,但可以节省大量开发时间。
  • 嗨@mav,您能否澄清一下SDK Tools 21.0 是否会自动执行此操作,还是需要配置?我尝试更新到最新版本(21.1),但我的构建时间并没有显着减少,即使我只更改了一行。在 Ubuntu 上使用 IntelliJ
  • @mav 我下载了最新的 android adt...我认为还有最后的 sdk 工具...但是我仍然在使用 CLI 进行本地构建时获得 30+ 构建时间...还有其他的吗解决方法是因为我在 ANDROID-SDK/platform-tools 目录中找不到 dx 应用程序?
  • @AlexStanese:它在 SDK/build-tools/version 中。
【解决方案2】:

即使在 21.1.1 中,在原始 dex.bat 中添加了 --incremental --no-optimize,它也很慢,所以我继续想办法,结果是:如果您按大小排序传递给 dex 的 .jar 文件,您获得更好的性能。

关注https://code.google.com/p/android/issues/detail?id=79166 获取更新,我希望他们同意,这会进入 vNext。

#!/usr/bin/perl
use strict;
use warnings;
#use Data::Dump qw(dump);
use List::Util qw(first), qw(sum);

# size of the argument, -s for files, -s on **/*.class for folders
sub size {
        if (-d $_) {
                # directory size is sum of all class files in the dir recursively
                # account for pre-dexing and compression with a 25% decrease
                return sum(map { size($_) * 0.25 } <$_/*.class>) || 0;
        }
        return -s $_; # use built-in size operator
}

my $dx_args_with_args =
   qr/^--(output|positions|(no-)?optimize-list|dump-(to|width|method)|num-threads|main-dex-list|input-list)$/;
my $nArgs = $#ARGV;
# last argument like --blah, those are for dx
my $lastArg = $nArgs - first { $ARGV[$nArgs - $_] =~ /^--/ } 0..$nArgs;
if ($lastArg != -1 && $ARGV[$lastArg] =~ /$dx_args_with_args/) {
        $lastArg += 1;
}

my @inputs = map { $_->[1] }
             sort { $a->[0] <=> $b->[0] }
             map { [size(), $_] }
             @ARGV[$lastArg + 1 .. $nArgs];

print join(" ", @ARGV[0..$lastArg], @inputs);

exit 0;

用法

  • 在您的道路上安装 Perl
  • 将上述perl脚本复制到ANDROID-SDK/build-tools/v.v.v/dx.pl
  • 在 ANDROID-SDK/build-tools/v.v.v/ 中重命名 dx
    Unix:将 dx 重命名为 dx-orig
    Windows:将 dx.bat 重命名为 dx-orig.bat
  • 添加一个新的替换 dx,它通过以下方式调用:
窗户:dx.bat
@echo off
setlocal
set args=%*
for /f "delims=" %%i in ('perl "%~dp0dx.pl" %args%') do set args=%%i
call "%~dp0dx-orig.bat" %args%
endlocal
Unix:dx
#!/bin/sh
dx-orig `perl dx.pl $@`

【讨论】:

    猜你喜欢
    • 2019-08-17
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多