Gradle升级3.1问题总结
背景:项目早期用的Gradle插件版本2.3.0,由于版本较老,无法使用Gradle新版本的特性,故需要升级至最新的Gradle版本。
有关Gradle3.0新版本的提升可参考官方介绍如下:
Android plugin for Gradle 3.0.0 includes a variety of changes that aim to address performance issues of large projects.
For example, on a sample skeleton project with ~130 modules and a large number of external dependencies (but no code or resources), you can experience performance improvements similar to the following:
Android plugin version + Gradle version | Android plugin 2.2.0 + Gradle 2.14.1 | Android plugin 2.3.0 + Gradle 3.3 | Android plugin 3.0.0 + Gradle 4.1 |
---|---|---|---|
Configuration (e.g. running ./gradlew --help) | ~2 mins | ~9 s | ~2.5 s |
1-line Java change (implementation change) | ~2 mins 15 s | ~29 s | ~6.4 s |
以上可以看出,新版本的Gradle在编译速度上提升很多,作为一名研发,亦是一名用户,是时候做一下升级,改善下用户体验了。
Gradle版本及Gradle插件版本的对应关系
Plugin version | Required Gradle version |
---|---|
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+ |
最新版本的Gradle插件版本是3.1.0,本着少踩坑的原则,采用次新版本3.0.0,所对应的Gradle版本是4.1。
跟着套路来吧,先把版本修改成目标版本,重新Sync Project,天呐,一堆错误,直接编译失败,问题整理如下:
问题1:
Gradle sync failed: Could not set unknown property 'enforceUniquePackageName' for object of type com.android.build.gradle.AppExtension. (5s 857ms)
解决方案:该插件强制所有库依赖项都有一个唯一的包名称,一般是设置false来禁用该选项。
enforceUniquePackageName = false 已经不支持,注释掉。
问题2:
Gradle sync failed: Could not get unknown property '输出apk名称为DwdRider_2015' for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.
Consult IDE log for more details (Help | Show Log) (1s 899ms)
解决方案:
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "rider_${android.defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
改为如下***********************************>
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "rider_${android.defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
}
}
参考:Android Gradle 3.0.0-alpha2 plugin, Cannot set the value of read-only property 'outputFile'
As Android plugin 3.0 migration guide suggests:
- Use all() instead of each()
- Use outputFileName instead of output.outputFile if you change only file name (that is your case)
Example from the guide:
// If you use each() to iterate through the variant objects,
// you need to start using all(). That's because each() iterates
// through only the objects that already exist during configuration time—
// but those object don't exist at configuration time with the new model.
// However, all() adapts to the new model by picking up object as they are
// added during execution.
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
问题3:
The specified Android SDK Build Tools version (25.0.2) is ignored, as it is below the minimum supported version (26.0.2) for Android Gradle Plugin 3.0.0.
Android SDK Build Tools 26.0.2 will be used.
To suppress this warning, remove "buildToolsVersion '25.0.2'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.
解决方案:
提示已经很明确了,当前的构建工具版本号25.0.2低于最低支持版本26.0.2,根据提示修改即可。
buildToolsVersion = "25.0.2"
改为
buildToolsVersion = "26.0.2"
问题4:
All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
解决方案:
插件 3.0.0 包含一项新的依赖项机制,这种机制可以在消费库时自动匹配变体。 也就是说,应用的 debug 变体将自动消费库的 debug 变体,等等。 这种机制也适用于使用风味的情况 - 应用的 redDebug 变体将消费库的 redDebug 变体。 要使这种机制发挥作用,插件现在要求属于给定风味维度的所有风味 - 即使您仅准备使用一个维度。
修改代码如下(app/build.gradle)
flavorDimensions 'tier'
productFlavors {
"yingyongbao" {
dimension 'tier'
}
}
Example from the guide:
// Specifies a flavor dimension.
flavorDimensions "color"
productFlavors {
red {
// Assigns this product flavor to the 'color' flavor dimension.
// This step is optional if you are using only one dimension.
dimension "color"
...
}
blue {
dimension "color"
...
}
}
问题5
Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.
Consider using CMake or ndk-build integration. For more information, go to:
https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile
To get started, you can use the sample ndk-build script the Android
plugin generated for you at:
/Users/suwantao/AndroidStudioProjects/trunk/flash/app/build/intermediates/ndk/yingyongbao/debug/Android.mk
Alternatively, you can use the experimental plugin:
https://developer.android.com/r/tools/experimental-plugin.html
To continue using the deprecated NDK compile for another 60 days, set
android.deprecatedNdkCompileLease=1532586669656 in gradle.properties
从提示可以看出,android.useDeprecatedNdk在新的版本将会被移除,请切换到新的构建系统,建议使用CMake o或者ndk-build ...如果想继续60天过时的NDK构建系统,可以在gradle.properties文件设置android.deprecatedNdkCompileLease=1532586669656
为了跟上时代的步伐,还是切到最新的构建系统吧。参考官方文档,可按照如下步骤执行。
- 1.删除android.useDeprecatedNdk = true
// Remove this line
android.useDeprecatedNdk = true
-
2.下载 NDK 和构建工具(若已经下载,跳过即可)
- 3.手动配置 Gradle
要手动配置 Gradle 以关联到您的原生库,您需要将 externalNativeBuild {} 块添加到模块级 build.gradle 文件中,并使用 cmake {} 或 ndkBuild {} 对其进行配置:
android {
...
defaultConfig {
ndk {
abiFilters "armeabi" ...
}
...
}
buildTypes {...}
//ndk-build模式
externalNativeBuild {
ndkBuild {
// Provides a relative path to your ndkBuild script.
path file("src/main/jni/Android.mk")
}
}
}
- 4.重新sync project即可
问题6:
More than one file was found with OS independent path 'lib/armeabi/libencrytkey.so'
原项目在jniLibs目录下已经存在libencrytkey.so文件,新的构建系统又重新生成libencrytkey.so,该文件目录在如下路径,解决该问题,把原libencrytkey.so文件删除即可。
问题7:
ABIs [armeabi] are not supported for platform. Supported ABIs are [armeabi-v7a, arm64-v8a, x86, x86_64].
解决方案:新版本的as默认下载的ndk版本是17,该版本已经不支持armeabi了,无奈只能降级处理,笔者降到版本 android-ndk-r16b
参考:
Android Plugin for Gradle Release Notes