Gradle for Android

394 阅读4分钟

一文件作用

  • 根目录下生成的gradle/wrapper文件夹作用是:
  1.  开发者不必安装Gradle工具即可获得Gradle运行环境,同时保证协同开发者使用的Gradle环境一致
    
    
     tips:你也可以修改gradle-wrapper.properties文件中的属性来改变gradle的配置
    
  • 根目录下生成的setting.gradle文件作用是:
  1.  定义哪些app模块应该包含在构建内(告诉androidGradle插件应该构建哪些module
  • 根目录生成的build.gradle文件作用:(顶层构建文件)
  1.  该文件作用是配置依赖 Gradle构建插件 的配置文件
     (比如com.android.tools.build:gradle:4.1.0插件就是google工程师开发的Gradle插件)
    
  2.   配置Gradle依赖下载中心仓库(比如jcenter()、google())
    

------------------------------------------------------------------------------------------------

buildscript {
    ext.kotlin_version = "1.4.10"
    repositories {
        //配置 预定义依赖仓库
        google()
        jcenter()
    }
    //配置依赖插件
    dependencies {
        //配置基于Gradle开发的Gradle插件
        classpath "com.android.tools.build:gradle:4.1.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
  • app模块目录生成的build.gradle文件作用(模块构建文件)
  1.  配置顶层构建文件 依赖的Gradle插件的 配置文件
     (如android{...}内部全部是androidGradle插件的独有的配置内容)
    
  2.   module依赖插件声明(如 android插件、kotlin-android)
    
  3.    配置当前module依赖的远程代码下载
     (gradle本身具有下载依赖的功能,所以该配置在android外部使用)
    

    tips:Gradle插件丰富了Gradle的功能就好比app丰富了android系统的功能是一个道理

二.androidGradle插件独有的配置文件详解

2.1androidGradle插件配置详解

上边阐述了生成各个文件的作用,接下来重点分析android代码块中关于android的每一项配置的作用(当前代码块内所有的代码都可以通过File--projectStructure进行图形化操作)

compileSdkVersion:用来编译应用的android API版本(比如使用低版本的方式写代码在低版本IDE就不会报错,但是切换到高版本就会IDE报错,尽量设置成最新,可以发现个版本差异)

 buildToolsVersion:构建工具编译器使用的版本号

defaultConfig代码块默认配置)里边的内容可以覆盖清单文件中的配置内容。为什么这么设计?

      试想如下场景,一个项目要做成多个影子应用,包名如果仅仅在清单文件配置,那么每次打包都要修改包名,但是R文件依赖清单文件,这就是很麻烦的一件事,于是google为了解耦包的问题,所以在该代码块内提供了覆盖的功能

applicationId :覆盖app打包过程中的包名

minSdkVersion:配置运行应用最小级别的API

targetSdkVersion:通知系统在特定的版本app已经兼容,特定版本的未来版本还需要系统自己去兼容

versionCode:app版本号(给机器看的)

versionName:app版本号(给人看的)

buildTypes代码块编译类型)里边的配置内容会覆盖默认配置

编译类型的代码块的作用:为了定义不同的编译类型(比如debug和release两种环境下编译需需要设置不同的url,每次修改代码太繁琐,可以通过定义编译类型自动选择不同的参数进行编译)

添加编译类型图形化界面如下图:

对应的会在编译类型中生成对应的配置如下:

 buildTypes {
        release {
           ......
        }
        debug {
           ......
        }
        ....
    }

当然,我们新建项目的时候仅仅存在release的编译类型,但是我们点击去执行运行,是debug模式运行,而我们没有进行debug模式的配置:原因是androidGradle插件默认配置了debug,如果我们在buildTypes 中定义debug,相同属性情况会覆盖默认配置(类似css就近原则)。那么如何切换到制定的编译类型呢?如下图:

选择不同的buildTypes,就会按照该类型下的配置内容进行运行。

tips:除了定义的debug类型,其他所有自定义编译类型都需要去配置签名文件,
      因为点击运行需要签名文件(其实debug类型底层默认配置了签名文件)

2.2buildTypes代码块配置详解

继续上边需求(动态配置url)的配置写法如下:

buildTypes {
        release {
            buildConfigField "String", "url", "\"http://192.168.1.158\""字符串类型需要转义符
            ......
        }
        debug {
          buildConfigField "String", "url", "\"http://192.168.1.159\""
          ......      
         }
        ....
    }

构建工具会根据配置生成BuildConfig.java文件,在代码中可以通过BuildConfig.url获取配置的值

上诉配置仅仅配置了代码中的动态参数,那不同编译类型如何动态配置资源文件呢?

buildTypes {
        release {
            resValue "string", "app_name", '"release张三"'
            ......
        }
        debug {
         resValue "string", "app_name", '"debug李四2"'
          ......       
        }
        ....
    }

构建工具会生成对应的res下的资源,你可以在xml中直接引用这些资源

当然这些配置都可以放到defaultConfig代码块,变成默认配置(建议相同的配置可以放到)。

三Gradle配置软编码

3.1 buildTypes软编码

2.2中我们讲解了编译的动态配置,但属于硬编码,大量的动态配置让配置文件显得臃肿,哪天我们想要修改这个值,还得找一堆这样的代码,可以把字段值定义到根目录下的gradle.properties文件中,在gradle中获取该值即可。获取方式直接引用

bbb=张三

buildConfigField "String", "APP_URL", "\"${bbb}\""

3.2Gradle参数软编码

实际生产环境中一般都是模块化或分组件化协同开发,多模块就面临多个模块构建文件。如何处理每个人的编译版本统一呢?这就需要把配置内容做到集中管理。

步骤:

1.在顶层构建文件buildscript代码块下创建ext{变量名称 =xxx’} 

2.在各模块构建文件使用$rootProject.ext.变量名称替换名称即可

当然该方式还对应图形化操作界面如下图:

tips:android项目各模块是否依赖不影响对ext的引用

如果大量的内容写入顶层构建文件显得非常臃肿,我们可以把配置文件单列出来,具体实现参考地址。这样就可以优雅的集中管理项目所有Gradle配置项参数。

tips:如果某个模块想要不使用集中配置参数,那么你可以在这个模块下的构建文件定义新的参数,
      模块构建文件定义的属性值会覆盖顶层构建文件定义的属性值

通过上边两个文件,我们把Gradle配置参数进行了集中管理,当然你也可以按照他们的引用方式,使用一个文件管理,但是我认为分开比较好,一个管理编译时期的参数不同,一个管理依赖的数据。

四补充buildTypes代码块配置详解

1配置签名文件(配置的目的是点击需要签名文件)

上边2.1说了需要为编译类型配置上签名文件(debug类型不用配是因为底层默认已经配置)。配置签名步骤:

  • 创建签名文件(Build-->Generate Signed Bundle or APK--->Create new)
  • 配置签名文件

图形化操作对应生成得代码如下:

android {

    signingConfigs {
        re {
            storeFile file('G:\\test.jks')
            storePassword '123456'
            keyAlias 'key0'
            keyPassword '123456'
        } 
         ......
 } 
  • 给不同的编译类型使用配置的编译文件

对应生成代码如下:

buildTypes {
        release {
            ......
            signingConfig signingConfigs.re
        }
     ......
    }

tips:如果不想创建签名文件可以使用:staging.initWith(buildTypes.debug)来复制默认的构建类型如下:

    staging {
            staging.initWith(buildTypes.debug)
             ......
        }

其他有用参数配置

applicationIdSuffix配置作用:包名追加---就是修改defaultConfig里边的applicationId属性

versionNameSuffix配置作用: 同理--就是修改defaultConfig里边的versionName属性

minifyEnabled 配置作用: 是否开启混淆(目的为了增加apk的安全性和缩小apk的文件大小),具体参考

五多组件开发Gradle配置

多组件是多模块的升级版,目的是为了解决大项目编译运行慢的问题。思路:通过参数配置在开发时期,组件可以变成可独立运行的mudule。打包时期,组件变成可以依赖的Library。

  • 在gradle.properties文件下定义一个boolean值

  • 在主module下依赖配置修改成如下:

    if (!runModule.toBoolean()) { implementation project(path: ':ModuleMine') }

  •  在每个可变得module下修改如下:

-------------------------------------------------------------------------------------------

if (runModule.toBoolean()) {
    apply plugin: 'com.android.application'
    apply plugin: 'kotlin-android'
} else {
    apply plugin: 'com.android.library'
    apply plugin: 'kotlin-android'
} 
  • 添加不同的配置清单文件如下(与buildTypes同级别):

-------------------------------------------------------------------------------------------

    sourceSets{
        main{
            if (runModule.toBoolean()){
                manifest.srcFile "src/main/xxx"
            }else {
                manifest.srcFile "src/main/xxx"
            }
        }
    }

通过以上配置我们即可实现一个参数控制是否单独编译。