# Groovy 语言

函数调用可以不加括号

配置闭包 android{}

# Gradle 配置

gradle 是基于 groovy 语言的项目构建工具

Android Studio 基于 gradle 来构建项目

## Project

入口配置文件

- buildscript 
  - 定义 gradle 所需仓库与依赖

- allprojects{}
  - 定义 Android 项目 所需仓库与依赖

```groovy
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {//这里是gradle脚本执行所需依赖，分别是对应的maven库和插件
    
    repositories {
        google()//从Android Studio3.0后新增了google()配置，可以引用google上的开源项目
        jcenter()//是一个类似于github的代码托管仓库，声明了jcenter()配置，可以轻松引用 jcenter上的开源项目
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'////此处是android的插件gradle，gradle是一个强大的项目构建工具
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {//这里是项目本身需要的依赖，比如项目所需的maven库
    repositories {
        google()
        jcenter()
    }
}

// 运行gradle clean时，执行此处定义的task任务。
// 该任务继承自Delete，删除根目录中的build目录。
// 相当于执行Delete.delete(rootProject.buildDir)。
// gradle使用groovy语言，调用method时可以不用加（）。
task clean(type: Delete) {
    delete rootProject.buildDir
}

```

## Module

### apply plugin 接口

```groovy
// 声明是Android程序，
//com.android.application 表示这是一个应用程序模块
//com.android.library 标识这是一个库模块
//而这区别：前者可以直接运行，后着是依附别的应用程序运行
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.crashlytics'
```

### android 配置

- signingConfigs 
  - 打包配置，生成apk文件时的配置
  - release
  - debug 
- compileSdkVersion
  - 设置编译时的Android版本
- defaultConfig
  - 项目基础信息
- buildTypes
  - 安装配置，安装apk时的配置
  - release
  - debug
- sourceSets
  - 配置目录指向
  - main
    - jniLibs.srcDirs
- packagingOption
  - 打包时，包依赖配置
- productFlavors
  - 多个渠道apk配置

其他配置

- lintOption
  - 代码扫描分析
- dependencies
  - 依赖关系

```groovy
// 声明是Android程序，
//com.android.application 表示这是一个应用程序模块
//com.android.library 标识这是一个库模块
//而这区别：前者可以直接运行，后着是依附别的应用程序运行
apply plugin: 'com.android.application'

android {
    signingConfigs {// 自动化打包配置
        release {// 线上环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
        debug {// 开发环境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
    }
    compileSdkVersion 27//设置编译时用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//项目的包名
        minSdkVersion 16//项目最低兼容的版本
        targetSdkVersion 27//项目的目标版本
        versionCode 1//版本号
        versionName "1.0"//版本名称
        flavorDimensions "versionCode"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//表明要使用AndroidJUnitRunner进行单元测试
    }
    buildTypes {// 生产/测试环境配置
        release {// 生产环境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.release//设置签名信息
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境，帮助国际化的东西，一般使用的不多
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化，减小zip体积，增加运行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀，一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀，一般使用的不多
        }
        debug {// 测试环境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.debug//设置签名信息
            debuggable false//是否支持断点调试
            jniDebuggable false//是否可以调试NDK代码
            renderscriptDebuggable false//是否开启渲染脚本就是一些c写的渲染方法
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化，减小zip体积，增加运行效率
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境，帮助国际化的东西，一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀，一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀，一般使用的不多
        }
    }

    sourceSets {//目录指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib库目录
        }
    }

    packagingOptions{//打包时的相关配置
        //pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
        // 表示当apk中有重复的META-INF目录下有重复的LICENSE文件时  只用第一个 这样打包就不会报错
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
        //这个是有默认值得 merges = [] 这样会把默默认值去掉  所以我们用下面这种方式 在默认值后添加
        merge 'META-INF/LICENSE'

        //这个是在同时使用butterknife、dagger2做的一个处理。同理，遇到类似的问题，只要根据gradle的提示，做类似处理即可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
    }

    productFlavors.all {
            //批量修改，类似一个循序遍历
        flavor -> flavor.manifestPlaceholders = [IFLYTEK_CHANNEL: name]
    }

    //程序在编译的时候会检查lint，有任何错误提示会停止build，我们可以关闭这个开关
    lintOptions {
        abortOnError false
        //即使报错也不会停止打包
        checkReleaseBuilds false
        //打包release版本的时候进行检测
    }

}

dependencies {
    
    //声明测试用例库
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


```

## Build Varient

为一个项目构建多个应用程序

### Edit Build Type

- Debug
- Release

### Edir Flavors

- 多渠道配置



## 文章

https://www.jianshu.com/p/e501e2bcf315

# 『译』Android Studio 合并多个 Manifest

```

        <provider
            android:name="com.sqwan.msdk.provider.SqFileProvider"
            android:authorities="${applicationId}.provider"
            android:grantUriPermissions="true"
            tools:ignore="MissingClass">
            <meta-data
                android:exported="false"
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_file"/>
        </provider>

        <!-- SQ APPID 参数（数字int型，数值一般较大） 非常重要，请替换为分配给游戏对应的参数 !-->
        <meta-data
            android:name="SQH5SDK.appid"
            android:value="${ZGAME_APP_ID}"/>

        <!-- 聚合 GameID 参数（数字int型，数值一般较小） 非常重要，请替换为分配给游戏对应的参数 !-->
        <meta-data
            android:name="SDK.GAMEID"
            android:value="${ZGAME_GAME_ID}"/>
        <!-- 37GameSDK 的配置结束 -->
        
        
                    signingConfig signingConfigs.interal
            proguardFiles getDefaultProguardFile('proguard-android.txt'), './proguard-rules.pro'
            //applicationId = "com.zapp.c37.demo"
            manifestPlaceholders["ZGAME_CHANNEL"] = "37_hw"
            manifestPlaceholders["ZGAME_GAME_ID"] = "48"
            manifestPlaceholders["ZGAME_APP_ID"] = "599"
```

