16

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

ant debug

有用。但它工作缓慢:

BUILD SUCCESSFUL Total time:

26 seconds

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

4

2 回答 2

13

我终于找到了解决方案!这有点骇人听闻,但它确实有效。

首先,转到您的 ANDROID-SDK/platform-tools 目录,然后将dxapp 重命名为其他名称,例如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 工具链时可能会遇到问题

更新:

谷歌发布了 SDK Tools 21.0,它使上述调整被废弃,因为它支持 pre-dexing。最后!

于 2012-08-28T09:39:06.680 回答
0

即使在--incremental --no-optimize原始 dex.bat 中添加的 21.1.1 中它也很慢,所以我继续想办法,结果是:如果您按大小对传递给 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/vvv/dx.pl
  • 在 ANDROID-SDK/build-tools/vvv/ 中重命名 dx
    Unix:重命名dxdx-orig
    Windows:重命名dx.batdx-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 $@`
于 2014-11-12T16:34:57.087 回答