简体   繁体   English

从命令行编译Android项目很慢

[英]Compiling Android project from command line is slow

I'm compiling my (fairly simple, just 5 files with few hundred LOC) app from command line on OSX using: 我正在使用以下命令在OSX上从命令行编译我的(相当简单,只有5个文件和几百个LOC)应用程序:

ant debug

It works. 有用。 But it works slowly: 但它运作缓慢:

BUILD SUCCESSFUL Total time:

26 seconds

Why is that? 这是为什么? It takes this much time even if I change only one line in one java file. 即使我只更改一个java文件中的一行,也需要很长时间。 Most of this time is spent in dex stage (about 20 seconds), which is AFAIK creating Dalvik bytecode. 大部分时间都花在dex阶段(大约20秒),这是AFAIK创建Dalvik字节码。 But my friend that also works on the same project on Windows using Eclipse says that compiling takes only a second or two on his machine. 但我的朋友也使用Eclipse在Windows上使用相同的项目,他说编译只需要一两秒钟就可以在他的机器上运行。 Is there anything I can do to speed up this proccess? 有什么办法可以加快这个过程吗?

I finally found a solution for this! 我终于找到了解决方案! It's a bit of a hack, but it works. 这有点像黑客,但它确实有效。

First, go to your ANDROID-SDK/platform-tools directory, then rename dx app to something else, like dextool , and finally create new dx file with contents: 首先,转到您的ANDROID-SDK / platform-tools目录,然后将dx app重命名为其他内容,例如dextool ,最后创建包含内容的新dx文件:

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

Replace "dextool" with the name you chose before. 将“dextool”替换为您之前选择的名称。 This will prepend (undocumented) --incremental attribute to every dex invocation, which will massively decrease build times by dexing only classes that have changed between builds. 这将为每个dex调用添加(未记录的)--incremental属性,这将通过仅对构建之间已更改的类进行dexing来大大减少构建时间。 Now it looks like this: 现在它看起来像这样:

[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 instead of 20s is a huge difference! 0.5秒而不是20秒是一个巨大的差异!

Edit - few remarks: 编辑 - 几点评论:

  • you have to compile your project at least once before using this, because it uses previous classes.dex file 你必须在使用它之前至少编译一次你的项目,因为它使用以前的classes.dex文件
  • you can run into problems when using other Android toolchains than ant 使用除ant之外的其他Android工具链时,您可能会遇到问题

UPDATE: 更新:

Google released SDK Tools 21.0, which renders above tweak absolete, because it does supports pre-dexing. Google发布了SDK Tools 21.0,它使得上述调整过时,因为它确实支持pre-dexing。 Finally! 最后!

Even in 21.1.1 with the --incremental --no-optimize added in the original dex.bat it is slow, so I went on to figure something out, the result is: if you order the .jar files passed to dex by size you get better performance. 即使在21.1.1中,在原始的dex.bat中添加了--incremental --no-optimize它也很慢,所以我继续想出一些东西,结果是:如果你订购传递给dex的.jar文件大小你会获得更好的表现。

Watch https://code.google.com/p/android/issues/detail?id=79166 for updates, I hope they agree and this goes into vNext. 请访问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;

Usage 用法

  • have Perl on your path Perl在你的道路上
  • copy the above perl script to ANDROID-SDK/build-tools/vvv/dx.pl 将上述perl脚本复制到ANDROID-SDK / build-tools / vvv / dx.pl
  • rename dx in ANDROID-SDK/build-tools/vvv/ 在ANDROID-SDK / build-tools / vvv /中重命名dx
    Unix: rename dx to dx-orig Unix:将dx重命名为dx-orig
    Windows: rename dx.bat to dx-orig.bat Windows:将dx.bat重命名为dx-orig.bat
  • add a new replacement dx which calls through: 通过以下方式添加新的替换dx:
Windows: dx.bat Windows: 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 Unix: dx
 #!/bin/sh dx-orig `perl dx.pl $@` 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM