Android(安卓)Gradle plugin升级 3.0.1 和升级 3.1.1遇到的坑
升级过程
将project下的build.gradle中的gradle plugin版本升级到3.0.1
dependencies { classpath 'com.android.tools.build:gradle:3.0.1' //原先为2.3.3}
修改后通过Sync project可以得知gradle-wrapper版本低于gradle plugin 3.0.1所要求的最低版本,根据提示将gradle 版本升级到4.1。
distributionUrl=https://services.gradle.org/distributions/gradle-4.1-all.zip //原先为 3.3
更改仓库,如下:
buildscript { repositories { ... // You need to add the following repository to download the new plugin. google() } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' }}
再次Sync project会出现以下错误,
Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
意思是需要我们在app/build.gradle加上默认的flavor dimension:
flavorDimensions "default" // 即以下说的风味维度
gradle plugin 3.0以上包含一项新的依赖项机制,这种机制可以在消费库时自动匹配变体。 也就是说,应用的 debug 变体将自动消费库的 debug 变体,等等。 这种机制也适用于使用风味的情况 - 应用的 redDebug 变体将消费库的 redDebug 变体。 要使这种机制发挥作用,插件现在要求属于给定风味维度的所有风味 - 即使您仅准备使用一个维度,也是如此。
这个属性主要用于不同渠道打包时的配置问题,至于它的使用具体请参考配置构建变体
更改依赖项配置
新配置 已弃用配置 行为 implementation compile 依赖项在编译时对模块可用,并且仅在运行时对模块的消费者可用。对于大型多项目构建,使用 implementation 而不是 api/compile 可以显著缩短构建时间,因为它可以减少构建系统需要重新编译的项目量。大多数应用和测试模块都应使用此配置。 api compile 依赖项在编译时对模块可用,并且在编译时和运行时还对模块的消费者可用。此配置的行为类似于 compile(现在已弃用),一般情况下,您应当仅在库模块中使用它。应用模块应使用 implementation,除非您想要将其 API 公开给单独的测试模块。 compileOnly provided 依赖项仅在编译时对模块可用,并且在编译或运行时对其消费者不可用。此配置的行为类似于 provided(现在已弃用)。 runtimeOnly apk 依赖项仅在运行时对模块及其消费者可用。此配置的行为类似于 apk(现在已弃用)。 注:compile、provided 和 apk 目前仍然可用。 不过,它们将在下一个主要版本中消失。
同时还需要修改注解处理器依赖项配置,即将
apt
改为annotationProcessor
,因为以后的gradle plugin将不再兼容android-apt 插件,修改如下:dependencies { ... annotationProcessor 'com.google.dagger:dagger-compiler:
' //原本为apt 'com.***'}接下来再rebuild或者直接run时,如果项目中有用到注解依赖的话,会出现找不到注解的情况,例如用到Dagger会出现
Error:(31, 34) 错误: 找不到符号符号: 类 DaggerAppComponent位置: 程序包 com.***.***.
该问题可以通过设置 module 的 build.gradle 处理,如下
android { ... defaultConfig { ... javaCompileOptions { annotationProcessorOptions { includeCompileClasspath true } } }}
不过官方并不建议这么使用,甚至在将来将会移除该选项,但是好像也没找到有其他解决方法。
修改完再sync依然会有问题,如下:
Error:(268, 5) error: style attribute '@android:attr/windowEnterAnimation' not found.Error:(268, 5) error: style attribute '@android:attr/windowExitAnimation' not found....Error:failed linking references.Error:java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for detailsError:java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for detailsError:com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
从这里来看好像是AAPT2的问题,所以从网上可以找到大量对该问题的解决方法都是在 project 的 gradle.properties中添加这样一行代码
android.enableAapt2=false
, 添加完之后也确实是可以解决了。
但是,加上这个之后,在以后升级3.1.1
时将无法使用instant run,会一直报错:Error: java.util.NoSuchElementException
,所以这里真正的解决方法是找到你的style文件,将里面所有的以@android
开头的都去掉 “@” 这个符号,例如:// 原先的<style name="PushInBottom"><item name="@android:windowEnterAnimation">@anim/push_bottom_in
- "@android:windowExitAnimation"
>@anim/push_bottom_outstyle>// 变更后的<style name="PushInBottom"><item name="android:windowEnterAnimation">@anim/push_bottom_in- "android:windowExitAnimation"
>@anim/push_bottom_outstyle>API变更
Variant API 变更,主要是 variant 的outputFile在使用上产生了变化,例如原本是output.outputFile
和output.outputFile.name
, 变更后应该使用output.outputFileName
,但涉及访问 outputFile 对象的更复杂任务将不再奏效。
manifestOutputFile变更,processManifest.manifestOutputFile()
函数不再可用,如果尝试调用该函数,将遇到以下错误:A problem occurred configuring project ':myapp'.Could not get unknown property 'manifestOutputFile' for task ':myapp:processDebugManifest'of type com.android.build.gradle.tasks.ProcessManifest.
取而代之的是通过调用
processManifest.manifestOutputDirectory()
来返回包含所有已生成 manifest 目录的路径, 然后,通过该路径找到某个 manifest 。下面的示例可以在 manifest 中动态更改版本代码:android.applicationVariants.all { variant -> variant.outputs.all { output -> output.processManifest.doLast { // Stores the path to the maifest. String manifestPath = "$manifestOutputDirectory/AndroidManifest.xml" // Stores the contents of the manifest. def manifestContent = file(manifestPath).getText() // Changes the version code in the stored text. manifestContent = manifestContent.replace('android:versionCode="1"', String.format('android:versionCode="%s"', generatedCode)) // Overwrites the manifest with the new text. file(manifestPath).write(manifestContent) } }}
参考文献
迁移到 Android Plugin for Gradle 3.0.0
更多相关文章
- RK3288 android7.1.2 插 UVCCamera 摄像头, android studio 调试9
- Android(安卓)重写onCreateOptionsMenu后菜单项不显示的问题
- Android(安卓)NDK开发指南(一) Application.mk文件
- note_24:踩坑之安装android studio 3.3.2并配置环境
- android源码中的c c++库( android中动态和静态版本都有的库)
- broadcastreceiver 静态注册无法正常运行
- 浅析Android中build.gradle的实用技巧
- DatePickerDialog 自定义样式及使用全解
- Android(安卓)4.0 wifi 和 Ethernet 的实现分析