记一次AndroidStudio 编译慢砸电脑的经历

申明:电脑最终没砸成。
问题描述:
AS使用jdk1.8后,jack编译器导致AS 的instant run 功能失效,导致每次都是重新来一次,如果项目复杂的话会特别耗时间

问题发现的过程:

做一个组件化demo的时候,使用了jdk1.8。结果每次项目编译都是10分钟以上,然后instant run也启动不了(as提示instant run disable when jack....)。

当时给这个问题下了两个结论:

  • 电脑配置实在太渣了

由于自己的电脑配置很渣,所以一直以为是电脑问题(之前用的公司台式机,该项目用的自己的笔记本(i3)。都在筹划着购买新电脑了。

  • 组件化后编译会变慢

这个结论有点牵强,如果真是这个问题网上肯定会有人碰到,结果各种搜也没找到跟这个相关的。

后来使用gradle build-profile命令查看编译耗时情况如下:

:app 5m47.67s (total)

task 所用时间
:app:transformClassesWithPreJackPackagedLibrariesForDebug 2m7.70s
:app:transformJackWithJackForRelease 1m28.25s
:app:transformJackWithJackForDebug 1m2.54s
:app:lint 22.736s
:app:mergeDebugResources 12.305s

查看到主要耗时就是这个jack编译造成的,我擦的,怎么又看到了这个Jack,这货TMD是谁啊?

经过各种搜才知道jdk1.8跟as的instant run冲突,然后恢复成1.7.发现不只是instant run可以使用了,连第一次的编译速度也变成了2分钟左右(首次没有instant run)。看来android对java8的支持挺坑的。当然主要是我电脑太渣所以差距才会这么大,如果电脑配置很高,估计连这个问题都发现不了吧。

问题原因:
官方文档中文版 使用 Java 8 语言功能

返回使用jdk1.7方式如下:把以下代码注释掉

    defaultConfig {
      applicationId "com.example.administrator.mousestore"
      minSdkVersion 15
      targetSdkVersion 26
      versionCode 1
      versionName "1.0"
      testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//        jackOptions {
//            enabled true//为true时使用jdk1.8的jack编译
//        }

  }
//        compileOptions {
//            sourceCompatibility 1.8
//            targetCompatibility 1.8
//        }

另外,如果你有其他module的话也需要处理下。
如果module是java module那请修改如下代码:

apply plugin: 'java'

dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

把sourceCompatibility和targetCompatibility改成1.7

关于jack编译器(以下copy知乎上的一个回答):

Jack是Android从Java 7到Java 8过渡时期的一次失败尝试。

具体来讲,在Java 7之前,Android app是使用javac+dx的方式编译出来的,即源代码java程序先由javac编译成可以在JVM上执行的class文件,再由dx工具将class文件转换成dex文件,这个dex文件就是apk里面的二进制代码。如图所示:

image

Java 8的时候,Google的工程师们推出了Jack(Java Android Compiler Kit),想要尝试用这套新的工具链替换原来的javac + dx,即直接从java代码编译到dex文件,如图:

image

为什么要替换原有的javac+dx 方法呢?原因可能有:

  1. 从java直接到dex,减少中间结果,可以加快编译速度;
  2. Jack工具直接处理java源代码,有更大的编译优化空间;
  3. javac属Oracle公司所有,Google想要摆脱Oracle的制约(猜测)。

总之Jack就这样被推出了,而且它能完成基本编译任务,也完全可以用来开发中小型应用。

但是,有很多基本编译功能之外的其他功能是Jack很难支持的,例如bytecode分析和重写,annotation处理等等。对于个人开发者来说,最直观的影响就是Android Studio里面的instant run功能,即app源代码被修改一小部分之后增量地编译修改的部分,从而更快地运行app。Instant run这个功能需要bytecode可分析和重写,所以Jack无法支持,必须每次从头开始编译,于是用了Jack之后,app编译会明显变慢。

正因为这些附加功能的缺失,Jack却一直无法很好地为大型企业及开源社区服务,而解决这些问题又很难。

于是,在今年3月,Google终于宣布,放弃了Jack,重新尝试用javac+dx的方法在Android里支持Java 8。

Over time, we realized the cost of switching to Jack was too high for our community when we considered the annotation processors, bytecode analyzers and rewriters impacted. -- James Lau, Product Manager

Jack的故事到这里就结束了,一次有意义的尝试宣告破产,令人惋惜。不知道未来还有没有可能卷土重来。

你可能感兴趣的:(记一次AndroidStudio 编译慢砸电脑的经历)