Android Studio 3.0及Gradle Plugin 3.0升级过程中踩到的那些坑

前言:

  2018转眼已经过去一快小半年,堕落了很长一段时间,觉得回到家乡小地方,没有了追求技术的热情。直到前段时间跟以前的同事聊的过程中发现自己已经脱离正轨了。虽然不再北上广深了,但是技术还是得靠自己去折腾。也许有一天回过头来看看,自己曾经那么爱android是吧。哈哈。废话不多扯了,直接进入今天要给大家带来的唠嗑。

正题:

大家都知道Android已经到android8了,开发工具也持续更新到Android Studio3.1了,gradle也更新到4.4了,也许你可能要问,我为啥要更新,用原来的2.×的版本不行么?行,怎么会不行呢,只是很多技术是向前看的,工具也是要跟上时代,才能达到事半功倍的效果,这几天我也是折腾很久,才升级好,那么我把我踩过的坑分享给大家是希望大家能避免我的折腾路。

1.Gradle Plugin升级到3.0.0及以上,修改project/build.gradle文件:

buildscript {
    repositories {
        ...
        // You need to add the following repository to download the
        // new plugin.
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'//这里知道是3.0.0以上就可以
    }
}

2.Gradle升级到4.1及以上,修改project/gradle/gradle-wrapper.properties文件:

distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

3.生成APK文件名属性outputFile变为只读

改完第一步后,编译会报如下错误:这个是生成APK的打包文件

Error:(88, 0) Cannot set the value of read-only property ‘outputFile’ for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=appDebug, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl.

之前的Apk打包文件类似这样:

  // 自定义导出apk名称
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                if (variant.buildType.name.equals('release')) {
                    def fileName = "mobiletianya-v${defaultConfig.versionName}-${defaultConfig.versionCode}-release.apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
                if (variant.buildType.name.equals('debug')) {
                    def fileName = "mobiletianya-v${defaultConfig.versionName}-${defaultConfig.versionCode}-debug.apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }
    }

而升级后由于outputFile属性变为只读,需要进行如下修改,直接对outputFileName属性赋值即可:

applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                if (variant.buildType.name.equals('release')) {
                    def fileName = "mobiletianya-v${defaultConfig.versionName}-${defaultConfig.versionCode}-release.apk"
                    outputFileName = fileName
                }
                if (variant.buildType.name.equals('debug')) {
                    def fileName = "mobiletianya-v${defaultConfig.versionName}-${defaultConfig.versionCode}-debug.apk"
                    outputFileName = fileName
                }
            }
        }
    }

4.关键字的依赖传递

  • api: 对应之前的compile关键字,功能一模一样。会传递依赖,导致gradle编译的时候遍历整颗依赖树
  • implementation: 对应之前的compile,与api类似,关键区别是不会有依赖传递
  • compileOnly: 对应之前的provided,依赖仅用于编译期不会打包进最终的apk中
  • runtimeOnly: 对应之前的’apk’,与上面的compileOnly相反

关于implementationapi的区别,主要在依赖是否会传递上。如:A依赖B,B依赖C,若使用api则A可以引用C,而implementation则不能引用。

这里更推荐用implementation,一是不会间接的暴露引用,清晰知道目前项目的依赖情况;二是可以提高编译时依赖树的查找速度,进而提升编译速度。详见SO的这个回答,讲得非常详细了:https://stackoverflow.com/questions/44413952/gradle-implementation-vs-api-configuration


以上四点是最基本的,实际应用中一写lib包的依赖关系主要也是围绕这几点来修改

注明:下面是一些遇到的小问题:

1.Aapt2异常

升级到3.0.0版本,编译之前正常的项目后报错Error:com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for

上面是官方的文档介绍,我们可以看到在gradle3.0.0中AAPT2是默认打开的,在项目的gradle.properties中添加android.enableAapt2=false,sync后就编译通过了

这几个是比较公用的,剩下那些是跟自己项目相关的,具体项目具体分析,后续继续更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值