Android Gradle 常用的配置

在 Android Studio 构建的项目中,基于 Gradle 进行项目的构建,同时使用 Android DSL (Domain Specific Language 领域专用语言)进Android 项目的配置。而 Gradle 是基于 Groovy 脚本语言进行开发,想要熟练掌握gradle的配置就得了解Groovy的基础以及Android DSL等知识。这里只整理下android 项目中常用的配置,需要更深入了解可以Groovy去搜索相关知识以及官方文档。

Gradle 基本

用Android Studio新建一个项目的时候,默认生成一大堆关于gradle的东西,其中最重要的是一个build.gradle的文件,结构如下:


1557299252(1).jpg
先看看项目下的build.gradle内容:
buildscript {
    repositories {
        google()
        jcenter()
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'//这行表示使用的gradle插件版本
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
    }
}
}

在 repositories {}脚本块中可以配置maven仓库,比如下面这两行表示使用国内阿里云仓库的镜像地址,可以加快某些仓库的加载速度

maven { url 'https://maven.aliyun.com/repository/google' }
maven{ url 'https://maven.aliyun.com/repository/jcenter'}
Module下的build.gradle内容:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.administrator.gitapplication"
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.squareup.okhttp3:okhttp:3.14.1'
}

解读:


apply plugin::指定用的是哪个插件,开发中常见的值有:
'com.android.application':Android APP插件(打包得到的是.apk文件)
    'com.android.library':Android库插件,当要创建一个库时使用(打包得到的是.aar文件)
    'java':普通的java插件(打包得到的是.jar文件)
defaultConfig{}用来配置一些默认属性 ,sdk版本,apk版本等基本属性,更多的属性下面介绍
buildTypes {}给不同版本的apk配置属性,常见的release ,debug等,可以配合productFlavors来配置多渠道打包
dependencies {}仓库依赖

常见配置介绍

1.signingConfigs 签名配置

要发布一个APK是需要签名的。使用android studio 可以通过build窗口下Generate Signed Apk命令来生成秘钥和签名。但是每次这么太麻烦,不符合程序猿的风格,于是就可以在gradle中配置签名信息:

 signingConfigs {
//可以根据不同需要配置不同的信息,在需要的地方引用即可
        debug {
            // 配置的这几行都是生成keystore时需要的
            storeFile file("keystore.keystore")
            storePassword "storePassword "
            keyAlias "keyAlias "
            keyPassword "keyPassword "
        }
        release {
            storeFile file("keystore.keystore")
            storePassword "storePassword "
            keyAlias "keyAlias "
            keyPassword "keyPassword "
        }
    }

配置完秘钥信息在buildTypes {}中使用

 buildTypes {
   debug{
            signingConfig signingConfigs.debug
        }
 release {
            signingConfig signingConfigs.release
        }
}

这样在编译不同版本的apk时就会使用不同的keystore,或者不使用签名


1557301659(1).jpg

但是这样配置签名信息不够安全,一些私密信息应该隐藏起来:
1.在项目的根目录下创建一个名为 keystore.properties 的文件,并包含以下信息:

storePassword=myStorePassword
keyPassword=myKeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation
1557301894(1).jpg

2.在build.gradle 文件中,按以下步骤操作来加载 keystore.properties 文件(必须在 android 代码块之前):

//这几行代码是加载keystore.properties中的信息,在需要的地方使用
keystoreProperties 获取信息。
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

android {
  ...
signingConfigs {
    config {
      keyAlias keystoreProperties['keyAlias']
      keyPassword keystoreProperties['keyPassword']
      storeFile file(keystoreProperties['storeFile'])
      storePassword keystoreProperties['storePassword']
    }
  }
}
...

2.buildTypes {}配置

debug {
         
            buildConfigField "boolean", "LOG_DEBUG", "true"//在BuildConfig文件中生成LOG_DEBUG字段
            minifyEnabled false //是否运行混淆文件
            zipAlignEnabled false//是否使用Zipalign优化
            //Android SDK中含一个“zipalign”的工具,它能够对打包的应用程序进行优化
              //在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效率
            debuggable true//能否进行debug
            shrinkResources false // 移除无用的resource文件
            signingConfig signingConfigs.debug//签名配置

        }
        release {
        
            buildConfigField "boolean", "LOG_DEBUG", "false"
            minifyEnabled true
            zipAlignEnabled true
            shrinkResources false // 移除无用的resource文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'//配置混淆文件
            signingConfig signingConfigs.release//签名配置
        }

在构建时,Gradle 将生成 BuildConfig 类,以便应用代码可以检查与当前构建有关的信息。可以使用 buildConfigField() 函数,将自定义字段添加到 Gradle 构建配置文件的 BuildConfig 类中,然后在应用的运行时代码中访问这些值。如下:

...
Log.i(TAG, BuildConfig.LOG_DEBUG);

3.使用的统一的版本号

在引入库的时候需要确定版本号,有时会因为版本号不同而产生问题,所以最好统一管理一些版本相关信息。在项目下的顶级 build.gradle增加ext代码:

buildscript {...}
allprojects {...}

//此块封装自定义属性并使其可供所有项目中的模块使用
ext {
    // 以下是可以定义的属性类型的几个示例。
    compileSdkVersion = 28
    buildToolsVersion = "28.0.3"

    //还可以使用它来指定依赖项的版本。 
     //模块之间的版本一致可以避免行为冲突。
    supportLibVersion = "28.0.0"
    ...
}

在module的build.gradle中使用ext代码

android {
    //使用以下语法访问在项目级别定义的属性:
   // rootProject.ext.property_name
  compileSdkVersion rootProject.ext.compileSdkVersion
  buildToolsVersion rootProject.ext.buildToolsVersion
  ...
}
...
dependencies {
  compile"com.android.support:appcompatv7:${rootProject.ext.supportLibVersion}"//groovy中的语法,双引号下执行 ${表达式}
    ...
}

4.与 manifest 共享属性

某些情况下,您可能需要同时在 manifest 和代码中声明相同属性 。如以下示例中所示,请在模块的 build.gradle 文件中定义一个属性并使其对 manifest 和代码均可用,而不必在多个位置更新相同的属性以反映更改。要了解详情

android {
  defaultConfig {
    def filesAuthorityValue = applicationId + ".files"
    manifestPlaceholders =
      [filesAuthority: filesAuthorityValue]
      buildConfigField("String",
                       "FILES_AUTHORITY",
                       "\"${filesAuthorityValue}\"")
  }
  ...
}
...

在 manifest 中,访问以下占位符:

<manifest>
  ...
  <application>
    ...
    <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${filesAuthority}"
      android:exported="false"
      android:grantUriPermissions="true">
      ...
    </provider>
  </application>
</manifest>

5.BuildVariants变体

buildTypes+productFlavors相结合,组成构建变体,buildTypes构建类型,主要就是debug(测试) ,release(线上)的分别。productFlavors产品口味,主要就是各种渠道版本。两个合体就会构建出不同的版本apk (总apk个数=构建类型个数*渠道个数).看图:


1557304085(1).jpg
 signingConfigs {
        debug {... }
        release {... }
    }

    productFlavors {
        ziyou_001 {...}
        huawei_021 {...}
    }

可以通过productFlavors来改变某个风味的属性:

    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name.split("_")[1]]
    }

    productFlavors.huawei_021 {
        flavor -> flavor.manifestPlaceholders = [app_name: "xxxx"]
    }

一次生成所有渠道包
打开命令行窗口,进入到工程的根目录下,输入

gradle assembleChinaProduceRelease

6.配置 DEX 选项

在 Gradle 将代码编译到 DEX 文件中时,使用以下属性可以缩短构建时间。

android {
  ...
  dexOptions {
  //设置可以同时启动的DEX进程的最大数量。
    maxProcessCount 8
//设置dex操作的最大内存分配池大小。
    javaMaxHeapSize "2g"
//使Gradle能够预先解决库依赖关系。
    preDexLibraries true
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352