Android 开发之 Gradle那些事儿(二)

模块的build.gradle

/标识本模块用什么gradle插件,常用的有: Android应用的->com.android.application
Android库->com.android.library / apply plugin ‘…’ /关于android
的所有特殊配置都在这里面,后面会结合例子详解
/ android {…}
/代码仓库,一般都配在项目的build.gradle下,模块下此项配置一般省略/ repositories{…} /* gradle
的依赖配置,定义了当前模块需要依赖的其他库/ dependencies{…} /自定义的变量和方法*/ def …

详解android代码块
compileSdkVersion
用哪个版本的Android SDK来编译此模块
buildToolsVersion
构建工具的版本,包括如打包工具aapt、dx、aidl这些,位于$SDK dir$/build-tools/目录下,一般我们都下了好多个版本

这里写图片描述

这里写图片描述

lintOptions代码静态检查配置项.
一般情况下,我们只用到abortOnError false表示当lint发现错误时,不中断gradle构建
所有配置项,列出如下,一般用不到:

lintOptions {
    // true--关闭lint报告的分析进度
    quiet true
    // true--错误发生后停止gradle构建
    abortOnError false
    // true--只报告error
    ignoreWarnings true
    // true--忽略有错误的文件的全/绝对路径(默认是true)
    //absolutePaths true
    // true--检查所有问题点,包含其他默认关闭项
    checkAllWarnings true
    // true--所有warning当做error
    warningsAsErrors true
    // 关闭指定问题检查
    disable 'TypographyFractions','TypographyQuotes'
    // 打开指定问题检查
    enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
    // 仅检查指定问题
    check 'NewApi', 'InlinedApi'
    // true--error输出文件不包含源码行号
    noLines true
    // true--显示错误的所有发生位置,不截取
    showAll true
    // 回退lint设置(默认规则)
    lintConfig file("default-lint.xml")
    // true--生成txt格式报告(默认false)
    textReport true
    // 重定向输出;可以是文件或'stdout'
    textOutput 'stdout'
    // true--生成XML格式报告
    xmlReport false
    // 指定xml报告文档(默认lint-results.xml)
    xmlOutput file("lint-report.xml")
    // true--生成HTML报告(带问题解释,源码位置,等)
    htmlReport true
    // html报告可选路径(构建器默认是lint-results.html )
    htmlOutput file("lint-report.html")
    //  true--所有正式版构建执行规则生成崩溃的lint检查,如果有崩溃问题将停止构建
    checkReleaseBuilds true
    // 在发布版本编译时检查(即使不包含lint目标),指定问题的规则生成崩溃
    fatal 'NewApi', 'InlineApi'
    // 指定问题的规则生成错误
    error 'Wakelock', 'TextViewEdits'
    // 指定问题的规则生成警告
    warning 'ResourceAsColor'
    // 忽略指定问题的规则(同关闭检查)
    ignore 'TypographyQuotes'
}

defaultConfig应用默认配置
defaultConfig下的配置项会动态的在build时配置AndroidManifest.xml里的项目,它的配置可以覆盖manifest里的配置(同一个)
applicationId : 应用唯一标识,区别于manifest清单文件下的package包名。Manifest下的package包名,必须配置,必须和java代码的包名和R资源类的包名一样。Gradle中如果不配applicationId也可以,它会默认读取Manifest下的package包名并与之保持一致,如果配了,可以独立任意命名(可以独立任意命名的好处是可以针对同一套代码,打出不同的版本包,如付费版 免费版 精简版 专业版,对于用户的手机来说,这些是不同的应用,一个手机可以装多个)。

这里写图片描述

这里写图片描述

minSdkVersion、targetSdkVersion
minSdkVersion : 安装application所需要的系统最低版本,低于该版本的系统都不可以安装该application。同时不能使用该level版本SDK所不具备的API。例如在minSdkVersion为8的application中调用 this.getActionBar() 就会出现Call requires API level 11 (current min is 8): Android.app.Activity#getActionBar的错误。这是因为ActionBar是在android 11才出现的新功能(new API)

targetSdkVersion : 随着 Android 系统的升级,某个系统的API的行为可能会发生改变,但是只要 APK 的 targetSdkVersion 不变,即使这个 APK 安装在新 Android 系统上,其行为还是保持老的系统上的行为,这样就保证了新系统对老应用的向前兼容性(系统会判断APK的targetSdkVersion,决定执行API的新行为还是老行为)。
当我们修改了APK 的targetSdkVersion 后,必须做完整的测试。

一般来说:minSdkVersion <= targetSdkVersion <= compileSdkVersion
用较低的minSdkVersion来最大限度的覆盖用户机型,用较高的compileSdkVersion和targetSdkVersion获得较好的编译和运行效果。
versionCode versionName mutiDexEnabled
versionCode : 比较版本号,Integer类型,用于版本升级比较大小用,用户不可见。
versionName : 展示版本号,String 一般 “主版本.次版本.小版本” 这样三段点分表示,用户可见。
mutiDexEnabled : 是否开启对多Dex的支持,解决单Dex类名、变量名、方法名超过65535而报错,布尔类型,一般配成true

buildConfigField、resValue使用
使用buildConfigField和resValue的好处 :可以利用gradle对项目进行动态配置,构建时会自动读取你定义的一些变量,并放在自动生成的BuildConfig类中,或者构建时自动帮你替换资源
语法如下:buildConfigField(resValue同样)
跟三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值
例如:

   buildConfigField "boolean", "AUTO_UPDATE", "false"
      

常见用途:动态配置服务器地址,日志开关、自动更新开关、APP显示名称、不同的key配置(如TalkingData在代码中初始化,需要分Debug和Release需要用不同的key)等,我们一般把配置在buildTypes下的release和debug下,取不同的值。
例如:

  debug {
            minifyEnabled false
            shrinkResources false
            debuggable true
            signingConfig signingConfigs.hidePwdDebug

            manifestPlaceholders = [
                    BUILD_TIME_VALUE : buildTime(),
                    UMENG_APPKEY_VALUE : "******"
            ]

            resValue "string", "app_name", "gradleDemoDebug"
            buildConfigField "boolean", "AUTO_UPDATE", "false"
            buildConfigField "String", "BASE_URL", "\"http://www.baidu.com.com/\""
            buildConfigField "String", "BASE_H5_URL", "\"http://www.baidu.com/\""
            buildConfigField "String", "TALKINGDATA_KEY", "\"********\""
        }
        release {
            minifyEnabled true
            zipAlignEnabled true
            shrinkResources true
            debuggable false
            jniDebuggable false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.readLocalConfFileDebug

            manifestPlaceholders = [
                    BUILD_TIME_VALUE : buildTime(),
                    UMENG_APPKEY_VALUE : "********"
            ]

            resValue "string", "app_name", "gradleDemoRelease"
            buildConfigField "boolean", "AUTO_UPDATE", "true"
            buildConfigField "String", "BASE_URL", "\"http://www.baidu.com.com/\""
            buildConfigField "String", "BASE_H5_URL", "\"http://www.baidu.com/\""
            buildConfigField "String", "TALKINGDATA_KEY", "\"********\""
        }

signingConfigs签名相关配置
签名相关配置项,在signingConfigs代码块下,一般可配debug, release, dev等多种不同类型的签名配置,有两种配置方法:
1.在类型代码块下,直接写入keystore的密码、别名、别名密码和keystore文件的相对路径。
优点:直观简洁 缺点:不是足够安全,keystore的密码和别名密码,赤裸裸的在那
例子:

   signingConfigs {
        unsafeDebug {
            storeFile file("./key/unsafeDebug.keystore")
            storePassword "123456"
            keyAlias "unsafeDebug"
            keyPassword "123456"
        }
    }

2.在类型代码块下,不直接明文写入密码这些,用变量替代,具体变量存放在自定义配置文件或者gradle.properties或者local.properties。这些文件不需要提交版本库,需要负责打包的人配置在本地就行,别人也看不到,提高了安全性。
例子 (变量存放在gradle.properties):

        hidePwdDebug {
            storeFile file(HIDE_STORE_FILE)
            keyAlias HIDE_KEY_ALIAS
            storePassword HIDE_KEY_PASSWORD
            keyPassword HIDE_STORE_PASSWORD
        }
这里写图片描述

例子 (自定义签名配置文件signing.properties):

    readLocalConfFileDebug {
            storeFile file("xxx.keystore")
            storePassword "******"
            keyAlias "xxx"
            keyPassword "******"
        }
//读取本地配置文件,替换掉readLocalConfFileDebug代码块下的配置项
//需在buildTypes引用readLocalConfFileDebug这个签名配置之前执行
File propFile = file('../config/signing.properties');
if (propFile.exists()) {
    def Properties props = new Properties()
    props.load(new FileInputStream(propFile))
    if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
            props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
        android.signingConfigs.readLocalConfFileDebug.storeFile = file(props['STORE_FILE'])
        android.signingConfigs.readLocalConfFileDebug.storePassword = props['STORE_PASSWORD']
        android.signingConfigs.readLocalConfFileDebug.keyAlias = props['KEY_ALIAS']
        android.signingConfigs.readLocalConfFileDebug.keyPassword = props['KEY_PASSWORD']
    } else {
        android.buildTypes.release.signingConfig = null
    }
} else {
    android.buildTypes.release.signingConfig = null
}

buildTypes {
    debug {
        signingConfig signingConfigs.hidePwdDebug
        //signingConfig signingConfigs.readLocalConfFileDebug
    }
}
这里写图片描述

buildTypes详解
buildTypes用来配置不同的构建类型(debug, release, dev, 其他自定义类型),每种类型下都可以定制自己个性化的配置项和配置值,当你配好你需要的构建类型后,sync一下gradle,配制出的类型会显示在Android Studio的”Build Variants”和”Gradle Project-Module-Tasks”下:

这里写图片描述

一个典型的buildTypes配置例子如下:

 debug {
            minifyEnabled false
            shrinkResources false
            debuggable true
            signingConfig signingConfigs.hidePwdDebug

            manifestPlaceholders = [
                    BUILD_TIME_VALUE : buildTime(),
                    UMENG_APPKEY_VALUE : "******"
            ]

            resValue "string", "app_name", "gradleDemoDebug"
            buildConfigField "boolean", "AUTO_UPDATE", "false"
            buildConfigField "String", "BASE_URL", "\"http://www.baidu.com.com/\""
            buildConfigField "String", "BASE_H5_URL", "\"http://www.baidu.com/\""
            buildConfigField "String", "TALKINGDATA_KEY", "\"********\""
        }

显然,有关signingConfig、buildConfigField、resValue这些的意义和使用场景及方法,前两小节已经说过,不再赘述。

其他
zipAlignEnabled : zip对齐优化
shrinkResources : 移除无用资源
minifyEnabled : 启用混淆
debuggable : 是否支持调试
jniDebuggable : 是否支持JNI调试
manifestPlaceholders : 替换清单文件里的占位变量值(如各种需在清单里配的key和额外有用数据;跟buildConfigField配置的区别是这个是替换清单里的变量,供清单文件使用。那个是在代码里生成,供代码里面的类读取和使用)

谢谢大家。完结撒花

这里写图片描述
这里写图片描述

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容