Gradle is essentially an automated build tool that uses a Groovy-based domain-specific language to declare project Settings.

  1. Gradle file in the root directory
Buildscript {// buildscript reference ext {kotlin_version = '1.3.72'} repositories {// plugin repository configuration Google () jcenter() mavenCentral()} Dependencies {/ / dependent plug-ins / / Google's Android Gradle plug-in classpath 'com. Android. View the build: Gradle: 3.5.3' / / NOTE: Do not place your application dependencies here; They belong // in the individual module build.gradle files // 'com. At meituan. Android. Walle: plugin: 1.1.6' / / kotlin plugin classpath "Org. Jetbrains. Kotlin: kotlin - gradle - plugin: $kotlin_version" / / greendao plug-in classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' //ARouter plugin classpath "com.alibaba: ARouter -register:1.0.2"}} allprojects Google () jCenter () mavenCentral() maven {url 'http://developer.seedland.cc/nexus/repository/maven-dev/' } maven { url 'https://jitpack.io' } } } task clean(type: Delete) {// Declare task Delete rootproject. buildDir// Delete home path buildDir folder}Copy the code
  1. Gradle file for app Module:
//引入构建需要用到的gradle插件工具库
//每个build.gradle自身是一个Project对象,project.apply()会加载某个工具库到project对象中
//apply plugin:'xxx' 会将project对象传递入工具库,然后通过插件中的Groovy文件来操作project对象的属性,以完善配置初始化信息
apply plugin: 'com.android.application'
apply plugin: 'walle'
apply plugin: 'kotlin-android'
apply plugin: 'org.greenrobot.greendao'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.alibaba.arouter'

//android{} ,dependencies{} 是函数方程式,使用闭包函数的编写方式, 相当于project.android(){} ,project.dependencies(){}
android {
    compileSdkVersion 30 //编译的sdk
    defaultConfig { //默认配置
        applicationId "com.ljy.publicdemo" //包名
        minSdkVersion 17 //最低支持版本
        targetSdkVersion 30 //支持的目标版本
        versionCode 1 //版本号
        versionName "1.0" //版本名
        multiDexEnabled true //dex分包支持
        //如果应用没有做国际化,可以让应用仅支持 中文的资源配置
        resConfigs "zh"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //测试脚本
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64'
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
        }


        //ARouter配置
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }

    signingConfigs {//签名配置
        key {
            keyAlias 'key0'
            keyPassword '666666'
            storePassword '666666'
            storeFile file('./ljy_key.jks')
        }
    }

    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'
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    flavorDimensions "jin"
    productFlavors {
        higher {
            applicationId "com.ljy.publicdemo"
            minSdkVersion 26
            buildConfigField 'boolean', 'isLite', "false"
//            resValue "string", "app_name_new", "JinDemo"
            manifestPlaceholders = [
                    app_icon    : "@mipmap/ic_launcher_normal",
                    channelName : "higher",
                    verNum      : "2",
                    app_name_new: "JinDemoHigher"
            ]
        }

        lower {
            applicationId "com.ljy.publicdemo.lite"
            minSdkVersion 17
            buildConfigField 'boolean', 'isLite', "true"
//            resValue "string", "app_name_new", "JinDemoLite"
            manifestPlaceholders = [
                    app_icon    : "@mipmap/ic_launcher_lite",
                    channelName : "lower",
                    verNum      : "1",
                    app_name_new: "JinDemoLower"
            ]
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            buildConfigField("boolean", "isDebug", "false")
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.key
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "LjyPublicDemo_${variant.buildType.name}_${variant.versionName}.apk"
                }
            }
        }
        debug {
            minifyEnabled false
            buildConfigField("boolean", "isDebug", "true")
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.key
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "LjyPublicDemo_${variant.buildType.name}_${variant.versionName}.apk"
                }
            }
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    // 配置数据库相关信息
    greendao {
        //数据库版本号
        schemaVersion 1
        // 设置DaoMaster、DaoSession、Dao 包名
        daoPackage 'com.ljy.publicdemo.greendao'
        //设置DaoMaster、DaoSession、Dao目录
        targetGenDir 'src/main/java'
    }

    //gradle的命名提示机制,让各module中资源名必须按一定前缀命名,有助于防止组件化多module时的资源冲突
    resourcePrefix 'app_'
}

walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}

tasks.withType(JavaCompile) {
    //在 Gradle 4.10 版本之后便默认使用了增量编译
    //如果在更老的版本需要启动增量编译,可以使用如下配置:
    options.incremental = true
    //解决java控制台输出中文乱码
    options.encoding = "UTF-8"
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation project(path: ':mylibrary')
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation project(':library')   
}

Copy the code

Gradle’s life cycle is divided into three phases:

1. Initialization: Settings. gradle declares modules, determines which projects will be added to the build process, and creates project objects including ':app', ':library',':datepicker',':heigher_setting',':lower_setting',':mylibrary' 2. Configuration: Execute build.gradle scripts of all projects according to the reference tree, and configure project objects. A project object consists of multiple tasks. Build: The run phase executes dependent tasks based on the task name passed by the gradle commandCopy the code
  1. Version parameter optimization

The build.gradle file for each module has some necessary attributes. In the same Android project, some attributes are required to be consistent in different modules. For example, if the reference to compileSdkVersion is inconsistent, the attributes will not be merged into the project. This will cause duplicate resources and increase package size and reduce compilation efficiency. There needs to be a unified, basic Gradle configuration

  • Optimization Solution 1: Set the parameters in common mode
// create a common_config.gradle file project.ext {compileSdkVersion = 30 buildToolsVersion = "30.0.0" minSdkVersion = 17 TargetSdkVersion = 30 applicationId =" com.ljy.publicdemo" versionCode = 1 versionName ="1.0"} // Refer to common_config on the first line of module gradle and refer to the property apply from like a static variable: "${rootproject. rootDir}/common_config.gradle"// reference additional configuration apply plugin: 'com.android.library' apply plugin: ${rootproject. rootDir}/common_config.gradle" 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion project.ext.compileSdkVersion buildToolsVersion project.ext.buildToolsVersion defaultConfig { minSdkVersion project.ext.minSdkVersion targetSdkVersion project.ext.targetSdkVersion versionCode project.ext.versionCode versionName project.ext.versionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } }Copy the code
  • Optimization 2: Use Android object configuration
// Android {} provides the android variable, so you can simplify the code further by adding a closure method in //project.ext of common_config.gradle to specify the project variable. CompileSdkVersion = 30 buildToolsVersion = "30.0.0" applicationId = "com.ljy.publicdemo" minSdkVersion = 17 TargetSdkVersion = 30 versionCode = 1 versionName = "1.0" setDefaultConfig = {extension -> // The closure parameter extension corresponds to the Android object extension.compileSdkVersion compileSdkVersion extension.buildToolsVersion buildToolsVersion extension.defaultConfig { applicationId applicationId minSdkVersion minSdkVersion targetSdkVersion targetSdkVersion versionCode versionCode versionName versionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "Consumer-rules.pro"} extension.databinding {enabled true}}} // can be used in bulid.gradle ${rootproject. rootDir}/common_config.gradle"// invoke the additional configuration of the apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin - android - extensions' android {/ / use the closure function input android project in this object to the function. The ext setDefaultConfig android buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } }Copy the code
  • Optimization 3: Using project object configuration (final version)
/ / common_config. Gradle: Project. ext {compileSdkVersion = 30 buildToolsVersion = "30.0.0" applicationId = "com.ljy.publicdemo" minSdkVersion = 17 targetSdkVersion = 30 versionCode = 1 versionName = "1.0" // Set app Module config setAppDefaultConfig = {extension -> // Reference the application plugin library extension.apply plugin: 'com.android.application' extension.description "app" setAndroidConfig extension.android setDependencies // Add the following dependencies to your application: 'com.android.library' extension.description "lib" setAndroidConfig extension.android setDependencies SetAndroidConfig = {extension -> // The closure parameter extension corresponds to the Android object extension.compileSdkVersion compileSdkVersion extension.buildToolsVersion buildToolsVersion extension.defaultConfig { minSdkVersion minSdkVersion targetSdkVersion targetSdkVersion versionCode versionCode versionName versionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" / / configure ARouter javaCompileOptions {annotationProcessorOptions {/ / route each module name the arguments = [AROUTER_MODULE_NAME: Extension. The project. The getName ()]}}} the extension. The dataBinding {enabled true}} / / set dependent setDependencies = {the extension - > extension.implementation fileTree(dir: 'libs', include: ['*.jar', '*. Aar'] / / every module needs application routing apt plug-in library to generate the corresponding code, need not repeat here. Write each module gradle extension. AnnotationProcessor 'com.alibaba:arouter-compiler:1.2.1'}} // Build.gralde simply passes the project object into the closure functionCopy the code
  1. Debug optimized

Business module debugging, start a single module as APP, and then use it for debugging test, so as to ensure separate debugging of individual modules;

Apply plugin: 'com.android.library' to apply plugin: 'com.android.library' 'com.android.application', the module as application module can be introduced into the APP building process; 2. Each application needs to be configured with applicationId 3. AndroidMainfest needs to be configured with Activity < Activity that starts by default android:name=".datepicker.DatePickerActivity" android:theme="@style/Theme.AppCompat"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> 4. project.ext {compileSdkVersion = 30 buildToolsVersion = "30.0.0" MinSdkVersion = 17 targetSdkVersion = 30 versionCode = 1 versionName = "1.0" // Control component module debugging isDatePickerDebug=true} 5. Apply the variable as a switch in the module's build.config: "${rootProject.rootDir}/common_config.gradle" if (project.isDatePickerDebug) { project.ext.setAppDefaultConfig Project / / Settings app configuration} else {project. Ext setLibDefaultConfig project / / lib configuration set} android {sourceSets {main {the if (project.isDatePickerDebug) { manifest.srcFile 'src/debug/AndroidManifest.xml' res.srcDirs = ['src/debug/res', 'src/main/res'] } else { manifest.srcFile 'src/main/AndroidManifest.xml' resources { exclude 'src/debug/*' } } } } } 6. In the original App Module, you need to remove the dependency of the separately debugged module if (! project.isDatePickerDebug) { implementation project(':datepicker') }Copy the code
  1. Resource Reference Configuration

Gradle has multiple ways to reference resources

(1) Use sourceSets to specify the file path

SourceSets {main {manifest. SrcFile 'SRC/main/AndroidManifest. XML'/path/AndroidManifest jniLibs srcDirs = ['libs']//so library path resources.srcdirs = [' SRC ']// all resource file path aidl. SrcDirs = [' SRC ']// aiDL file path renderscript.srcdirs = [' SRC ']// RenderScript file path res.srcDirs = ['res']//res Asset file path asset. srcDirs = ['assets']// Asset asset file path}}Copy the code

The resources, (2) to dynamically add res buildTypes, productFlavors resValue variables, defined in resValue can dynamically add resources, cannot replace, if the resource name repetition, gradle resources will be prompted to repeat

resValue "string", "app_name_new", "JinDemo"
Copy the code

(3) You can specify resources of a specific size, and define resConfigs in buildTypes, productFlavors

android {
    ...
    defaultConfig {
        ...
        resConfigs "zh","en"//剔除不需要的国际化
        resConfigs "hdpi","xhdpi","xxhdpi","xxxhdpi"//剔除自身,三方库,sdk中不需要的dpi资源
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters 'armeabi', 'armeabi-v7a' //, 'x86', 'arm64-v8a', 'x86_64', 'mips', 'mips64'
        }
    }
}
Copy the code

ProductFlavors can be written with buildConfigField, which can be read directly into BuildConfig. It is possible to indirectly enable code to read the variables of AndroidManifest by manifestplaceholder in conjunction with meta-data in AndroidManifest

  productFlavors {
        higher {
            buildConfigField 'boolean', 'isLite', "false"
            manifestPlaceholders = [
                    app_icon    : "@mipmap/ic_launcher_normal",
                    channelName : "higher",
                    verNum      : "2",
                    app_name_new: "JinDemoHigher"
            ]
        }
  }
Copy the code

Gradle load priority

In build.gradle, there are four functions in descending order of priority:

buildTypes > productFlavors > Main > dependencies
Copy the code
I am Jinyang, if you want to advance and learn more dry goods, welcome to pay attention to the public number “jinyang said,” receive my latest article