升级过程

  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
  2. 更改仓库,如下:

    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'    }}
  3. 再次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 变体。 要使这种机制发挥作用,插件现在要求属于给定风味维度的所有风味 - 即使您仅准备使用一个维度,也是如此。

    这个属性主要用于不同渠道打包时的配置问题,至于它的使用具体请参考配置构建变体

  4. 更改依赖项配置

    新配置 已弃用配置 行为
    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.***'}
  5. 接下来再rebuild或者直接run时,如果项目中有用到注解依赖的话,会出现找不到注解的情况,例如用到Dagger会出现

    Error:(31, 34) 错误: 找不到符号符号:   类 DaggerAppComponent位置: 程序包 com.***.***.

    该问题可以通过设置 module 的 build.gradle 处理,如下

    android {    ...    defaultConfig {        ...        javaCompileOptions {            annotationProcessorOptions {                includeCompileClasspath true            }        }    }}

    不过官方并不建议这么使用,甚至在将来将会移除该选项,但是好像也没找到有其他解决方法。

  6. 修改完再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>
  7. API变更
    Variant API 变更,主要是 variant 的outputFile在使用上产生了变化,例如原本是 output.outputFileoutput.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

更多相关文章

  1. RK3288 android7.1.2 插 UVCCamera 摄像头, android studio 调试9
  2. Android(安卓)重写onCreateOptionsMenu后菜单项不显示的问题
  3. Android(安卓)NDK开发指南(一) Application.mk文件
  4. note_24:踩坑之安装android studio 3.3.2并配置环境
  5. android源码中的c c++库( android中动态和静态版本都有的库)
  6. broadcastreceiver 静态注册无法正常运行
  7. 浅析Android中build.gradle的实用技巧
  8. DatePickerDialog 自定义样式及使用全解
  9. Android(安卓)4.0 wifi 和 Ethernet 的实现分析

随机推荐

  1. Android接口回调,最简单的理解方式
  2. 关于Activity的启动模式
  3. 【BUG修补匠】 Android微信支付返回码-1
  4. Android(安卓)为点击事件添加震动效果
  5. 在Android(安卓)中Fragment 中嵌套使用Fr
  6. Android颜色透明度(不透明度)计算
  7. Android中与ViewRoot相关的一些概念
  8. Android(安卓)OOM 排查与解决——图片加
  9. Android(安卓)IPC系列--序列化机制
  10. TextView(文本框)详解