本文总结了在Android实际项目开发(本地编译)和集成(CI环境下编译)过程中,常见编译问题和解决思路。
查看报错信息
大部分编译问题,通过查看报错信息即可确定原因。例如语法不正确、找不到类、import包名有误、资源文件格式不正确等。不能理解的错误信息,可以在网上搜索、咨询其他人。
如果Android Studio中并没有给出足够充足的错误信息,可以使用Gradle命令行编译查看更为详细的信息,详见后文说明。
常规检查
这里列举一些编译失败时的常规检查项,可以解决大部分问题。
- 代码版本:检查代码是否切到正确分支、是否为最新版本。本地推荐使用SourceTree查看Git记录;Jenkins环境下可以通过Log查看代码的commit id。
- 对于多工程项目,需要检查依赖的库是AAR还是源码。
- Build Variant:检查Android Studio中的Build Variants窗口,是否选择了正确的Build Variant(BuildType和ProductFlavor)。
- 检查Gradle版本:一般使用工程中Gradle Wrapper指定的Gradle版本编译。Android Studio环境下,在
Preferences - Build,Execution,Deployment - Gradle
设置页选择Use default gradle wrapper(recommended)
;命令行环境下使用./gradlew
执行Gradle命令。 - 检查网络情况:Gradle提示下载依赖项失败时,可能是网络问题。例如网络异常、无法连接国外网站、开启了全局代理不能访问内网,从而没法访问内网中的私有Maven仓库等。
清缓存
常规检查一切正常,还没有解决问题时,可以根据实际情况,选用不同程度的清缓存手段然后重试。
-
清除AS的Cache:执行AS菜单中的
File - Invalidate Caches / Restart
,可以清除Android Studio的一些缓存。对于XML预览的问题,使用这个方法常常会有效。 -
清除build文件:执行AS菜单中的
Build - Clean Project
。此操作可以清除build目录中生成的R文件、解压的AAR、生成的APK/AAR等文件。 -
手动删除所有build文件:clean操作并不能删除所有build目录中的内容。可以手动删除主工程和每个子模块下的build目录,也就是所有编译时产生的文件。
-
删除Gradle远程仓库缓存(JAR/AAR):Gradle会在处理依赖项时,自动下载远程JAR/AAR到本地的Maven仓库,以后使用这些依赖项时不会再重新下载。少数时候,由于网络、服务端异常等原因,下载的文件可能出现损坏或错误导致编译失败,此时即使反复执行Clean操作也解决不了问题,需要清除本地Maven仓库中缓存的文件。以MacOS为例,操作如下。
1
2
3
4
5
6
7
8
9
10切换到Gradle使用的本地Maven仓库
cd ~/.gradle/caches/modules-2/files-2.1/
ls
com.facebook.fresco
com.facebook.react
com.flurry
com.google.code.gson
...
找到工程依赖的AAR模块名,删除该目录 -
清除Project配置信息:删除主工程下的
.idea
目录、每个模块下的*.iml
文件。.idea
目录保存了当前工程的各个模块信息、编译参数、当前工程的各种配置等,*.iml
文件为每个模块的信息。 -
清除Android Studio缓存和设置:Android Studio本身也有缓存以及设置文件,有时也是编译失败的原因,可以尝试清除。以MacOS为例,操作如下。
1
2
3
4
5
6
7
8
9
10
11
12切换到Library目录
cd ~/Library
查找到所有Android Studio相关的文件夹
find . -name "*Android*Studio*"
./Application Support/AndroidStudio3.0
./Caches/AndroidStudio3.0
./Caches/AndroidStudio3.0/tmp/AndroidStudio.21cd198f-7c25-4d3f-a047-19ee1a86939b
./Logs/AndroidStudio3.0
./Preferences/AndroidStudio3.0
删除相关文件夹,注意Preferences是AS的配置文件,删除后会清除AS的所有配置
重试
- 在同步(Sync)阶段发生的错误,可点击Android Studio工具栏中的
Sync Project With Gradle Files
按钮重试。 - 在编译阶段发生的错误,可重新尝试编译。
- 命令行直接调用Gradle编译,可以排除所有Android Studio引入的问题,一般可执行
./gradlew clean assembleDebug
编译,根据实际Gradle配置可能有所不同。 - 重启Android Studio、重启电脑、换电脑尝试、重装系统……
排查
代码
同样的代码,如果其他人编译正常,说明代码多半没有问题;如果都编译不了,说明代码可能存在问题。
Gradle命令行环境下能编译,通常说明代码没有问题。
获取完整错误信息:使用Gradle命令行编译
有时候Android Studio提示编译失败,但没有有效的错误信息,此时借助Gradle命令行能看到更详细的信息。
1 | 切换到主工程根目录 |
JAR/AAR反编译
由于版本覆盖、AAR编译出错、网络等原因,有时候提示找不到JAR/AAR中的Symbol(即引用,包括类、方法、变量等),但源码git记录中有这个Symbol,这时可以尝试反编译JAR/AAR查看其class文件,确定是否引入了错误的JAR/AAR。
- 解压AAR得到JAR:通过unzip命令行解压AAR文件;或在桌面环境下,将AAR扩展名改为zip,然后用相关工具解压。AAR解压后通常会得到JAR文件和Android资源文件。
- 查看JAR文件:使用JD-GUI工具打开JAR文件(JD-GUI网上可下载;也可以用相应的命令行工具),即可看到反编译后的源码。
- 高版本的Android Studio可以直接打开并反编译AAR和JAR文件。
快速编译插件
尝试关闭快速编译插件,例如Android Studio自带的Instant Run,第三方的编译加速插件等。
Gradle插件
一些Gradle插件也常会导致编译失败,可以禁用后重试编译。
常见异常
找不到R文件
- 资源文件异常,例如XML的标签不匹配,二进制文件异常(例如图片文件扩展名错误)。这种情况有时Android Studio没有有效报错信息,需要通过Gradle命令行发现问题。
- 命令行编译没有问题,但在Android Studio中报错。这个可能是Android Studio的BUG,多尝试几次同步。
- R文件过大,超出了Android Studio中Java文件大小限制。Mac系统下,打开
/Applications/Android\ Studio.app/Contents/bin
目录,编辑idea.properties
文件,修改idea.max.intellisense.filesize
的值(通常默认为2500,可以改成25000;如果没有这一项则新增一行)。
备注:在工程同步完成后,R文件保存在
build/generated/source/r
目录下,可以在这个目录下找是否正常生成了对应包名的R文件。
找不到Symbol
- 代码有问题。
- Android Studio代码窗口中报错,但可以编译通过。这个一般是因为同步时在build目录生成的class文件异常,尝试clean/清除build目录/重启AS后重试。
- 下载的远程库有错。参考前面的清除远程库缓存。
电脑卡顿严重
无论是AS还是命令行编译Android工程时,都是由Gradle执行编译任务,Gradle基于Groovy,运行在JVM上,消耗内存较多,因此常会因为内存不足导致电脑卡顿。系统内存不足时,整个电脑都会很卡。实际经验表明,内存16G的MacBook在物理内存占用率达到13G左右,就可能开始卡顿。
Gradle可配置Deamon,会给每个工程生成一个Deamon进程,Deamon进程会常驻后台处理源码,提高编译速度。有时无用的Gradle Deamon进程没有正常退出,会持续占据内存,因此必要时可以手动终止java进程。在Mac系统中打开“活动监视器”(Spotlight搜索或在LaunchPad找),切换到内存标签,关闭占内存过高的java进程和Android Studio进程,然后重试编译。
重启电脑常常也可以大幅降低无用进程对内存的消耗。
更换内存更大的电脑;加内存条……
Android Studio卡顿严重
编译很慢,Android Studio卡顿严重,但电脑不卡,可能是因为Android Studio最大内存设置的太小。
Mac系统下,打开/Applications/Android\ Studio.app/Contents/bin
目录,编辑studio.vmoptions
文件调整内存限制。