Gradle 手记|记录我使用过的 build 基本配置(不断更新中。。。

Posted HLQ_Struggle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gradle 手记|记录我使用过的 build 基本配置(不断更新中。。。相关的知识,希望对你有一定的参考价值。

岁月蹉跎,流失了岁月。

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

不瞒各位大佬,我想混个杯子,杯子被猫猫干碎了…

小厂猿猿一枚,原谅我没见过世面的样子,😂

先放置一张目前 Demo 中的结构图:

总是要点滴积累,慢慢跟着鸡老大学习,万一某天优秀了呢?

真的要细说 Gradle,恐怕目前能力还是有限,仅仅了解皮毛,简单分享,欢迎交流~

一、Gradle 基本配置

其实这块更应该成为封装项目的 basic build 配置,以便于后续的 module 可以减少大量重复性的内容,一方面冗余,另一方面也带来了更高的维护成本。

1、basic.gradle

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {

    // 指定用于编译项目的 API 级别
    compileSdkVersion Versions.compileSDK
    // 指定在生成项目时要使用的 SDK 工具的版本,Android Studio 3.0 后不需要手动配置。
    buildToolsVersion Versions.buildTools

    // 指定 Android 插件适用于所有构建版本的版本属性的默认值
    defaultConfig {
        // 最低兼容版本
        minSdkVersion Versions.minSDK
        // 最高支持版本
        targetSdkVersion Versions.targetSDK
        // 内部版本标识
        versionCode 1
        // Apk 版本信息 - 用户可见
        versionName "1.0"

        // 仅保留中文资源。此处根据产品内容进行相关设置,如果仅仅支持中文,建议配置,进一步减少 apk 大小
        resConfigs "zh"
        // 启用多 dex 文件
        multiDexEnabled true

        ndk {
            // 设置支持的SO库架构
            abiFilters "armeabi", "x86"
        }

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    // 配置 Java 编译(编码格式、编译级别、生成字节码版本)
    compileOptions {
        encoding = 'utf-8'
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
 
    kotlinOptions { 
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }

    // 开启视图绑定 兼容 Gradle 4.x 及以上版本
    buildFeatures {
        dataBinding = true // 其实保留一个就好了,DataBinding 包含 ViewBinding
        viewBinding = true // gradle 5.x +
    }

    lintOptions {
        // lint 异常后继续执行
        abortOnError false
    }

    // 禁止 AAPT 优化 png 图片
    aaptOptions {
        cruncherEnabled = false
    }

}

/**
 * implementation:不会向下传递,仅在当前 module 生效; api:向下传递,所依赖的 module 均可使用
 */
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation Deps.kotlinStdlibJdk7
    implementation Deps.appcompat
    implementation Deps.coreKtx

    testImplementation Deps.junit
    androidTestImplementation Deps.extJunit
    androidTestImplementation Deps.espressoCore
}

2、app 下 build.gradle

apply plugin: 'com.android.application'

apply from: "../basic.gradle"

android {

    // 获取本地私密信息配置 具体 local.properties 请看第三小节
    Properties properties = new Properties()
    properties.load(project.rootProject.file("local.properties").newDataInputStream())
    def jksDir = properties.getProperty('jksDir')
    def jksAlias = properties.getProperty('jksAlias')
    def jksPassword = properties.getProperty('jksPassword')

    // 指定 Android 插件适用于所有构建版本的版本属性的默认值
    defaultConfig {
        applicationId "com.pwccn.fadvisor"
    }

    // 签名信息配置(视项目情况而定)
    // 一般更侧重直接配置 config 并写入 release 信息,便于直接 debug 模式下调试例如支付等功能
    signingConfigs {
        config {
            v1SigningEnabled true
            v2SigningEnabled true
            storeFile file(jksDir)
            storePassword jksPassword
            keyAlias jksAlias
            keyPassword jksPassword
        }
    }

    // 封装项目的所有构建类型配置
    buildTypes {
        debug {
            // 二级包名 根据项目情况选择是否添加此项
            applicationIdSuffix ".debug"
            // 停用图片压缩
            crunchPngs false
            // 开启调试
            debuggable true
             // 对调试 build 停用 Crashlytics
            ext.enableCrashlytics = false
            // 禁止自动生成 build ID
            ext.alwaysUpdateBuildId = false
            // 签名配置
            signingConfig signingConfigs.config 
            // 关闭资源缩减
            shrinkResources false
            // 关闭代码缩减
            minifyEnabled false
            // 关闭 zipAlign 优化
            zipAlignEnabled false 
            // 混淆文件
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        release {
            // 关闭调试
            debuggable false
            // 签名配置
            signingConfig signingConfigs.config
            // 启用资源缩减
            shrinkResources true
            // 启动代码缩减
            minifyEnabled true
            // 开启 zipAlign 优化
            zipAlignEnabled true 
            // 混淆文件
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // multiDex 相关配置
    dexOptions {
        // 设置运行内存
        javaMaxHeapSize '4096m'
        // 增加每个 dex 字符串索引限制 2^16 -> 2^32
        jumboMode true
        // 是否保存 被运行时注解的类 保存至主dex
        keepRuntimeAnnotatedClasses false
        // 最大进程数 默认为4
        maxProcessCount 4
        // 线程数
        threadCount 4
        // 默认开启预编译 dex lib
        preDexLibraries true
    }

    // 产品变体/特性 这块详细内容请看第二小节
    flavorDimensions "default"
    productFlavors {
        beta {
            // 小例子
            buildConfigField "int", "hostType", "1"
            buildConfigField "boolean", "LOG_DEBUG", "true"
        }
        release {
            buildConfigField "int", "hostType", "3"
            buildConfigField "boolean", "LOG_DEBUG", "false"
        }
    }

    // 生成构建后输出的 Apk 名称
    applicationVariants.all { variant ->
        if (variant.buildType.name != "debug") {
            variant.getPackageApplicationProvider().get().outputDirectory = new File(project.rootDir.absolutePath + "/apk")
        }
        variant.outputs.all { apkData ->
            def fileName
            if (variant.buildType.name == 'debug') {
                fileName = "A_D_v"
            } else if (variant.buildType.name == 'release') {
                fileName = "A_R_v"
            }
            def timeStamp = new Date().format("yyyyMMdd_HHmmss")
            def apkName = fileName + variant.versionName + "_" + variant.flavorName + "_${timeStamp}" + ".apk"
            apkData.outputFileName = apkName
        }
    }

}

/**
 * implementation:不会向下传递,仅在当前 module 生效; api:向下传递,所依赖的 module 均可使用
 */
dependencies {
    // ...
}

二、buildConfigField 使用

在构建时,Gradle 将生成 BuildConfig 类,以便应用代码可以检查与当前构建有关的信息。而通过 buildConfigField 可以添加我们所需要的自定义属性字段。

例如基本的日志开关,之前采用的是 true/false,发布版本手动变更,某些情况下发包前会遗忘此出需要变更。

针对我之前这种法子做个小小升级,在原有 gradle 文件中添加如下内容:

android {
    // 封装项目的所有构建类型配置
    buildTypes {
        debug {
            // Log 控制器 - 输出日志
            buildConfigField "boolean", "LOG_DEBUG", "true"
            // ...
        }
        release {
            // Log 控制器 - 禁止输出日志
            buildConfigField "boolean", "LOG_DEBUG", "false"
            // ...
        }
    }
}

随后 Build 之后变会根据当前构建类型在 BuildConfig 中插入此变量:

public final class BuildConfig {
  // ...
  // Fields from build type: debug
  public static final boolean LOG_DEBUG = true;
}

使用时直接 BuildConfig.LOG_DEBUG 即可。

三、local.properties 存放证书密钥

其实这块我们也可以直接写入到 build 中,但是不是相对来说并不安全吗,所以特意将这块放置在 local.properties 文件中。

# 证书信息
jksDir = ../jks/HLQ_Test.jks
jksAlias = HLQ_Test
jksPassword = 12345678

番外

1、巧用 README

不知道大家有没有遇到过这个情况,当新入职一家公司的时候,项目 clone 下来之后,很多东西并不是很了解,问同事吧,同事也在忙,自己看的一头雾水。曾经在知乎看到一个大佬这么说过:

  • 多写一行注释,与人方便,与己方便。

个人还是建议巧用 README,记录项目常用的一些东西,方便之后的小伙伴快速上手~

这里附上一张我之前项目的事例,也是在尝试,欢迎提供更好建议~

在这里我截个之前负责的项目记录的 README 做个抛砖引玉吧~

THK

以上是关于Gradle 手记|记录我使用过的 build 基本配置(不断更新中。。。的主要内容,如果未能解决你的问题,请参考以下文章

Gradle 手记|记录我使用过的 build 基本配置(不断更新中。。。

Gradle 手记|记录我使用过的 build 基本配置(不断更新中。。。

Gradle 手记|记录我使用过的 build 基本配置(不断更新中。。。

使用Android Studio调试系统应用之TvSettings:build.gradle

如何在 build.gradle 中获取 Bamboo 内部版本号

android开发里跳过的坑-AS导入NDK工程提示错误 No such property: sdkHandler for class: com.android.build.gradle.Librar