文章目录
- 前言
- 场景1:从GitHub拉的项目,gradle下载很慢
- 场景2:kotlin jvm指定版本问题
- 场景3:高版本的项目在低版本的IDE打开报错
- 场景4:正常运行的项目某天突然要花很长时间才能build成功
- 场景5:Minimum supported Gradle version is 7.0. Current version is 6.8.2
- 场景6:Using different JDK locations on different processes might cause Gradle to spawn multiple daemons
- 场景7:同一个库导了几个版本的包
- 场景8:multiple script definitions are applicable for this script
- 场景9:taks list不见了
- 感谢
前言
比较神奇啊,经常会遇到gradle的问题,记录一下,方便查阅。
场景1:从GitHub拉的项目,gradle下载很慢
解决办法1:不要让软件去下载gradle,修改成已经下载好的版本即可
小明从GitHub上拉了一个项目,瞅了一眼,C:\Users\Administrator.gradle\wrapper\dists目录发现没有gradle-5.6.4-all文件夹,但是有gradle-6.1.1-all文件,新项目要用5.6.4,直接打开项目,下了半天,解压报错了:
Error:Failed to open zip file. Gradle’s dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
下什么下,直接改成本地已经有的版本
- 修改了项目根目录下build.gradle
//classpath 'com.android.tools.build:gradle:3.6.4'
//修改后
classpath 'com.android.tools.build:gradle:4.0.1'
- 修改了项目根目录/gradle/wrapper/gradle-wrapper.properties
#distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
#修改后
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
修改之后打开项目,同步一下,错误消失了。
解决办法2:自己下,自己解压
去http://services.gradle.org/distributions/去下了一个gradle-5.6.4-all.zip文件,他来到C:\Users\Administrator.gradle\wrapper\dists\gradle-5.6.4-all目录,发现有一个奇怪命名的文件夹(这个命名其实就是此下载包的sha1值)。进去删干净,把刚刚翻墙下的gradle-5.6.4-all.zip放进去,然后手动解压。
重启Android Studio,Invalidate caches and restart。大多数情况下是ok的。另外可以多装几个版本的IDE。
老版本Android Studio下载,推荐同时装3.5、4.1.0以及最新的预览版。可以一个版本一套配置,也可以都用一套,具体参考我这篇【Android Studio配置复用】。
场景2:kotlin jvm指定版本问题
新安装4.1.1的Android Studio加载项目报错:
New Gradle Sync is not supported due to containing Kotlin modules using an unsupported plugin version
乍一看好像时gradle版本有问题,其实不然。
因为软件默认的Kotlin Compiler是1.6,而gradle文件里写了1.8,所以只需要在Settings->Other Settings->Kotlin Compiler->Target JVM version将1.6改成1.8,然后点一下同步按钮(没错,那只大象)。
补充:gradle使用jdk版本指定以及gradle内部的一些设置
相信很多小伙伴还是用的jdk8,一般配置如下
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
useIR = true
}
Gradle 构建工具使用 Android Studio 中设置的默认 JDK 版本。以前版本默认使用 JDK 8,从4.2开始发生了变化,默认的 JDK 版本变为了 JDK 11。稍微改一下就可以用了
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
useIR = true
}
场景3:高版本的项目在低版本的IDE打开报错
This version of Android Studio cannot open this project, please retry with Android Studio 4.0 or newer
解决办法很简单,用高版本的IDE打开就行,如果硬是要用低版本打开,那需要修改ide插件版本和gradle版本。
Plugin version和Gradle version对应表
插件版本 | 所需的 Gradle 版本 |
---|---|
1.0.0 - 1.1.3 | 2.2.1 - 2.3 |
1.2.0 - 1.3.1 | 2.2.1 - 2.9 |
1.5.0 | 2.2.1 - 2.13 |
2.0.0 - 2.1.2 | 2.10 - 2.13 |
2.1.3 - 2.2.3 | 2.14.1+ |
2.3.0+ | 3.3+ |
3.0.0+ | 4.1+ |
3.1.0+ | 4.4+ |
3.2.0 - 3.2.1 | 4.6+ |
3.3.0 - 3.3.3 | 4.10.1+ |
3.4.0 - 3.4.3 | 5.1.1+ |
3.5.0 - 3.5.4 | 5.4.1+ |
3.6.0 - 3.6.4 | 5.6.4+ |
4.0.0+ | 6.1.1+ |
4.1.0+ | 6.5+ |
4.2.0+ | 6.7.1+ |
分析一波,你的Android Studio是3.6版本,运行的项目需要4.0,如果想要此项目在3.6上运行,则需要修改
classpath "com.android.tools.build:gradle:3.6.3"
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
因为版本不同,gradle语法也可能有变化,可能会报错,需要自行解决。
场景4:正常运行的项目某天突然要花很长时间才能build成功
-
清缓存
File->Invalidate Caches 选择invalidate and restart
-
设置gradle
设置全局gradle允许离线工作。
如果是老版本的IDE,windows在File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle,ios在preferences… -> Build, Execution, Deployment -> Build Tools -> Gradle。
勾选’Offline work’。 -
将下列默认目录位置的列表从病毒扫描和Windows搜索索引中排除
- Gradle cache: %USERPROFILE%.gradle
- Android Studio projects: %USERPROFILE%\AndroidStudioProjects
- Android SDK: %USERPROFILE%\AppData\Local\Android\SDK
- Android Studio system files: %USERPROFILE%.AndroidStudio\system
目前看来还有有一点用,但是作用不大。
- 修改工程目录下的gradle.properties文件
#设置允许最大内存
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#允许并行构建
org.gradle.parallel=true
# 允许守护进程(高版本gradle是默认打开的,不需要设置)
org.gradle.daemon=true
场景5:Minimum supported Gradle version is 7.0. Current version is 6.8.2
这种情况是工程目录下gradle文件忘记改了,和gradle-wrapper.properties里的对不上。
//可能你和我一样,只记得修改gradle版本,忘记修改plugin版本了😅
//classpath("com.android.tools.build:gradle:7.0.0-beta03")
classpath("com.android.tools.build:gradle:4.2.0")
android studio软件目录下plugins里有个gradle文件夹,里面存放了相关的jar包。要注意区分gradle plugin和gradle,这2个不是一个东西。
场景6:Using different JDK locations on different processes might cause Gradle to spawn multiple daemons
意思很简单,gradle使用的jdk版本和工程使用的jdk版本不一样,提示了一个警告。首先,如果不指定,gradle默认会使用系统环境变量的JAVA_HOME指定的jdk,这个jdk是可以换的。都用一个jdk版本即可解决问题。
IDE从4.2.0开始,jdk设置移到了gradle这,如图:
场景7:同一个库导了几个版本的包
这是很正常情况,因为你依赖的某个包他也有依赖的包,虽然缓存会下很多,但是其实gradle都帮你处理了。jar包冲突的大多数原因都是是本地lib和远程依赖之间的问题。
如果没有配置gradle环境变量,在teminal内使用gradlew app:dependencies打印moudule名为“app”的依赖树,可以加上–scan 参数,结束后会提示是否生成构建报告( 构建扫描是gradle4.3版本出现的)
点开链接,输入邮箱收邮件就可以通过地址去下载依赖树记录了。补充一下,如果不需要分析,也可以使用命令直接导出到本地txt文本,比如
//直接导出dps.txt文本,路径为D:\haizhuo\Download\buildSrcDemo77下
D:\haizhuo\Download\buildSrcDemo77>gradlew :app:dependencies --configuration releaseRuntimeClasspath > dps.txt
可以使用dependency-tree-diff项目提供的jar包比较2个文本的变化,当然使用git或者svn这种去比较也是比较ok的。
依赖树示例可以看出,一个库导了几个版本的包是很正常事。想统一,需要自己梳理自己的导入库的版本。
使用configuration 参数指定打印类型为implementation
gradlew :app:dependencies --configuration implementation
对于错误transformClassesWithJarMergingForDebug
Error:Execution failed for task ‘:app:transformClassesWithJarMergingForDebug’.
>com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry:
- 对于声明式依赖,同一个库的不同版本,gradle会自动使用最新版本来进行依赖替换、编译。
- 一个项目不同模块合并的时候,可能发生jar包冲突,但是原因大多是本地jar和远程gradle依赖冲突造成的。
这里找到原因之后,使用exclude排除某些模块即可
示例
implementation (project(':appframework')){
exclude group: 'com.google.android.material'
}
场景8:multiple script definitions are applicable for this script
报错的地方是setting.gradle.kts,提示是KotlinSettingScript和KotlinBuildScript。然后我把这段注释了
//dependencyResolutionManagement {
// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
// repositories {
// google()
// mavenCentral()
// jcenter() // Warning: this repository is going to shut down soon
// maven { url=uri("https://jitpack.io") }
// }
//}
dependencyResolutionManagement 允许为构建的所有项目配置依赖项解析。然后指定了模式RepositoriesMode.FAIL_ON_PROJECT_REPOS意思是项目中直接或通过插件直接声明的任何存储库都将触发构建错误。
目前没找到解决办法,可以尝试重启IDE忽略此错误。
场景9:taks list不见了
偶然间发现gradle的任务列表不见了。使劲点那只小象也没有。
解决办法是gradle设置里取消勾选 Do not build Gradle task list during Gradle sync,之后Sync Project with Gradle Files。
这不就出来了
补充1:关于墙外的资源下载缓慢
默认使用jcenter还有google等,以便在依赖库有紧急更新时能第一时间获取。
对日常的拉取速度有追求,可考虑使用以下远程仓库(是国内同步仓库,存在 1 天左右的时差),其中jcente和google用得比较多一点。
项目目录下build.gradle修改repositories下
repositories {
//省略...
//https://repo1.maven.org/maven2/
maven { url'https://maven.aliyun.com/repository/central/' }
//http://jcenter.bintray.com/
maven { url'https://maven.aliyun.com/repository/jcenter/' }
//central仓和jcenter仓的聚合仓
maven { url'https://maven.aliyun.com/repository/public/' }
//https://maven.google.com/
maven { url'https://maven.aliyun.com/repository/google/' }
//https://plugins.gradle.org/m2/
maven { url'https://maven.aliyun.com/repository/gradle-plugin'}
}
了解更多请查看阿里云云效 Maven
补充2:因为代理造成的拉包失败
小明成功把5.6.4的gradle问题解决后,发现下载工具3.6.4的时候又报错了。
Could not resolve all dependencies for configuration ':classpath'.
Connect to 127.0.0.1:1080 [/127.0.0.1] failed: Connection refused: connect
小明在任务管理器没发现1080端口的任务。后来发现是代理的问题,在Android Studio内部关闭代理是没用的,需要手动在C:\Users\Administrator.gradle目录的gralde.properties里删除配置。
补充3:关于gradlew与gradlew.bat
Gradle是一个构建工具,它是用来帮助我们构建app的,构建包括编译、打包等过程。Gradle 是基于groovy语言实现(基于JVM的语法和java类似的脚本语言)的一个Android编译系统, google针对Android编译用groovy语言开发了一套dsl,这就是gradle。
用gradle的指令构建app,需要用到gradlew(即gradle wrapper的简写)。
gradlew为Linux下的shell脚本,gradlew.bat是Windows下的批处理文件。
gradlew使用标准格式
gradlew [option...] [task...]或gradlew [task...] [option...]
option表示选项,task表示任务。具体用哪种格式可以根据个人爱好决定。
常用命令
gradlew -v 版本号
gradlew clean 清除app目录下的build文件夹
gradlew build 检查依赖并编译打包 gradlew build 命令把debug、release环境的包都打出来,如果正式发布只需要打Release的包
gradlew assembleDebug 编译并打Debug包
gradlew assembleRelease 编译并打Release的包
assemble还可以和productFlavors结合使用,多渠道打包
gradlew installRelease Release模式打包并安装
gradlew uninstallRelease 卸载Release模式包
补充4:硬件角度提高gradle速度
如果你的电脑是机械盘放的ide软件、sdk文件、.gradle文件、jdk文件、ndk文件等等。那么建议你装个固态盘,把常用的一些文件和软件都放进去。这样速度会快一点。
补充5:手动下载jar包放入gradle缓存里
一直不太清除为啥有些软件下载的时候,还要告诉我他的sha1值,后来我浏览gradle文件缓存的时候,发现了这个sha1原来是文件夹名。比如
J:\Android\.gradle\caches\modules-2\files-2.1\com.squareup.okhttp3\okhttp\4.9.0\8e17601d3bdc8cf57902c154de021931d2c27c1\okhttp-4.9.0.jar
8e17601d3bdc8cf57902c154de021931d2c27c1这个就是sha1的值,自己手动下只需要在对应的包下新建文件夹,然后复制粘贴。
补充6:关于设置环境变量GRADLE_HOME和GRADLE_USER_HOME
-
设置GRADLE_HOME,以gradle 6.5-all为例
首先去http://services.gradle.org/distributions/下载6.5的all版本,然后放在J:/Android下。
然后Path新增一条 %GRADLE_HOME%\bin。设置完后调出命令行,输入gradle -v查看。 -
GRADLE_USER_HOME设置
GRADLE_USER_HOME是存放gradle的路径。
android studio自带gradle的plugin
软件中这些只是gradle中的部分jar包。
我们运行Android Studio时候,下载的gradle都会存放在这个路径。GRADLE_USER_HOME 有点类似 Android Studio里的Settings->Build,Execution,Deployment->Build Tools->Gradle 下的Gradle user home设置。
总结:不建议设置gradle的环境变量,因为软件里设置gradle user home就好,除非你是那种喜欢用命令行到处执行gradle命令的人。
感谢
如何使用 Gradle 显示您的 Android 项目的依赖树?
scans.gradle.com
gradle用户手册
Android开发gradle常见问题