1 问题
(1) 当项目中引用的第三方模块太多,打开Android Studio的时候就会非常慢,提示一直在解决模块依赖,点击sync按钮同步第三方代码的时候也是巨慢,慢的原因是:
在gradle中引用第三方模块时采用maven方式依赖,每次打开Android Studio或者点击sync按钮时,都会去maven中央仓库去取第三方的库文件,一般是jar或者aar文件
如果本地没有该文件,则下载回来,由于通过网络访问Android Studio默认的maven中央仓库jcenter很慢,因此就导致同步会非常耗时,尤其是第一次同步,或者clean后重新build的时候,一般都会在十分钟左右,
即使库文件已经下载到本地了,也会去访问maven仓库的,因此当过多的通过maven方式依赖第三方库的时候Android Studio就会非常慢
(2) Android Studio为什么编译很慢?
Android Studio在编译的时候,如果没有同步第三方代码,或者任何一个gradle文件发生变化后,没有去同步,那么点击运行按钮会自动先同步,也就是先同步后编译,平时我们感觉编译慢的原因主要是同步代码太慢,真正同步完成后编译其实是很快的
2 maven依赖是啥?
svn用来管理文本文件,但它不擅长管理二进制文件,这个时候maven就登场了,简单点说,maven就是管理二进制文件的svn,这样说应该可以理解了吧。一般我们使用别人的库需要下载jar文件然后依赖到我们的工程,现在作者将jar文件发布到公共的maven仓库中,在gradle中我们只需要简单的像下面这样:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">dependencies {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用square开源的网络访问框架okhttp</span>
compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.squareup.okhttp:okhttp:2.5.0'</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
同步代码时,Android Studio就会自动去下载作者发布的jar(或者aar)文件,如果作者发布了新的版本,则只需要简单的修改一下后面的版本号即可,不要这个库,直接删掉这行代码即可,是不是瞬间觉得相当方便啊
在web开发中,只需要使用maven插件就能实现同样功能,只是依赖的写法不同。这就是解决不同模块不同版本依赖的方法—maven大法。
然而由于我们访问国外的服务器太慢,这么先进的生产工具就成了鸡肋,这是造成Android Studio卡、慢的根源
3 解决方法
方法一:
(1) 当第一次同步代码后,第三方库都下载到本地了,将gradle设置为offline模式,这样下次就不必访问网络了,这样同步速度从几分钟缩短到几秒钟,但缺点是一旦引入新的maven依赖,本地不存在这个库文件,还是得去访问网络,同样同步慢
方法二:
(2) 自己搭建maven仓库,将常用的第三方库放在自己搭建的maven服务器上,这样访问内部的maven服务器就快多了,又方便分模块开发和打包,但这样对服务器的管理麻烦,技术含量高,比较适合需要分模块开发的大型项目,而且当多个模块开发不同步,需要对模块分版本进行依赖、打包、发布的时候,必须采用这种方式,例如:模块A已经开发完毕,模块B正在开发,但这个时候要发版本了,怎么办呢?解决办法就是依赖模块B的上个版本,也就是上个版本的aar文件
方法三:
(3) 将第三方库下载到本地,然后将代码复制到自己的项目中,这种方法是在代码级别上直接使用别人的代码,优点是再也不用依赖别人的库,项目模块少,库与自己项目融为一体,缺点是复制的时候太辛苦了,不仅要复制代码文件,还要复制资源文件,容易出错,另外耦合比较严重,删除这个库的时候也非常麻烦,同时别人的代码也破坏了自己的代码风格和命名规范
方法四:
(4) 推荐的方法是:尽量使用第三方库的jar、aar文件导入自己的项目,或者将第三方库下载到本地,然后当做一个本地模块导入自己的项目,不要再使用gradle中的maven依赖了
这样就不用苦逼的去复制代码,删除的时候也很方便,只需删除模块即可,实现模块即插即用,缺点是会导致项目的模块太多,不美观,以及很多eclipse写的库导入Android Studio后还要自己修改才能编译通过,很多库是Android工程,不是标准意义的Android library,
好在现在很多有名的库都专门提供了library,直接导入即可,还有Android Studio已经可以直接将eclipse工程当做一个module导入了,所以这种方法还是很简单的
这种方法也就是以前eclipse使用第三方库的方法
4 直接引用aar文件的方法
Android Studio卡的主要原因是gradle去下载maven仓库中的库文件时速度太慢,那么我们直接去maven仓库将第三方库文件下载回来,引用到项目中就可以解决问题了。然而Github上很多项目只给出了maven依赖的使用方法,压根没有给出jar或aar文件的地址,我们以Android上比较有名的facebook的图片加载框架fresco为例:
https://github.com/facebook/fresco
在fresco的Github主页上只给出了下面这种使用方法:
<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.facebook.fresco:fresco:0.9.0+'</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
怎么办呢?难道只能使用maven依赖去慢慢下载吗?如果你搭建过maven服务器或者发布过自己写的框架,你就知道,其实我们最终使用的还是别人打包好的jar或aar文件,上面这行字符串只不过是指向这个aar文件而已,最终gradle还是要把aar文件下载回来,那么问题来了,这个文件究竟在哪儿呢?下面我们就找出这个文件:
(1) 百度”maven”仓库
选择第一个,我们就进入了maven中央仓库,也就是下面的网址
maven中央仓库:http://mvnrepository.com/
(2) 搜索fresco,一般关键字就是库的名称啦
对比一下maven依赖字符串com.facebook.fresco,所以选择第一个
可以看到有很多版本,你会发现上面的maven字符串后面的版本号是不是和这里的版本号吻合了,其实maven依赖字符串就是告诉gradle怎么去找这个库文件。点击红色框中最新版本0.9.0
在写这篇文章的时候,最新版是0.9.0,后来这个网站改版了,aar文件下载方法有点变化,所以我更新了下面这一段,这个时候版本已经到0.11.0了,后面的版本请你自己灵活的变通一下,下面我们来下载aar文件
点进去之后会发现有很多文件,解释一下,后缀为xxxx-javadoc.jar的文件是帮助文档,xxxx-sources.jar的文件是源码,这两个都不是我们需要的,我们需要的是单纯的xxx.jar文件,或者xxx.aar文件,如图:
好了,找到啦,直接点击fresco-0.11.0.aar就可以下载了,其实maven依赖字符串就是告诉gradle怎么去找到这个aar文件
那么怎么使用aar文件呢?
(3) 使用aar文件
aar文件和jar文件不同,jar文件只包含类文件,aar文件不仅包含类文件,好包含资源文件,例如:图片,布局文件等。aar文件使用方法如下。
在app的build.gradle文件中加入如下代码:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//本地仓库,用于引用aar文件</span>
repositories {
flatDir {
dirs <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'libs'</span>
}
}
dependencies {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//facebook的图片加载框架fresco</span>
compile(name: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'fresco-0.9.0'</span>, ext: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'aar'</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
(4) 点击sync按钮同步代码,如果还是找不到库中的类,那么点击运行按钮,即使运行不起来,只要运行一次就可以找到我们引入的库中的类了。
(5) 好了,到这里就学会了跳过maven依赖,直接使用aar文件的方法,是不是很简单呢。搞清楚了原理,gradle的maven依赖其实也就那么回事,用不好反而成了鸡肋
5 其他一些注意事项
(1) 尽量删除不用的module,因为每次sync的时候会去同步所有的gradle文件,即使我们的主工程不使用它也会去同步,sync是全局的
(2) 自己下载gradle到本地,然后在Android Studio指定gradle的位置,避免第一次创建项目时去下载gradle,那也是巨慢的一个过程
(3) 减少同步代码的次数,也就是没事别点sync按钮,每次同步代码都是非常消耗资源的过程,次数多了也就卡了
6 总结
(1) 网上说的有关解决Android Studio卡顿的方法,诸如:给gradle开启专门的守护线程,增大Android Studio的内存,开启gradle离线模式等,经过实践证明,并没有什么卵用,因为他们并没有找到Android Studio卡的真正原因是gradle同步代码时网速太慢
7 说明
博主写这篇文章,主要是因为之前在做项目时,使用了十几个maven依赖的第三方库,结果每次打开Android Studio或者点击sync按钮同步代码时都要超过十分钟时间,十分钟那是必须滴,同步一次都可以喝杯咖啡了,实在忍无可忍了,遂百度解决方法,然而发现网上那些方法并没有什么卵用,于是自己摸索出了解决方法,将所有引入的第三方库全部改为引用aar文件或者jar文件,不再使用maven依赖,哈,瞬间就快了
经过博主实践,使用这种方法,同步代码从原来的十多分钟缩短到了一分钟之内,遂著此文以记之