阅读 525

defaultConfig——安卓gradle

目录
一、前言
二、defaultConfig
1、搞清楚几个问题
2、defaultConfig 的存在形式
3、defaultConfig 中属性的意义
4、defaultConfig 中方法的意义
三、写在最后

一、前言

我们在安卓开发中,编译的任务是由 gradle 来负责的。但很多时候我们进入 build.gradle 文件中,有种似懂非懂的感觉,所以小盆友总结并分享自己学习到的点滴。

话不多说,今天分享的是在我们的每个模块下(应用级)build.gradle 文件中,android 下的 defaultConfig 属性

二、defaultConfig

1、搞清楚几个问题

在分享 defaultConfig 前,我们需要先弄清楚几个问题,这几问题之前一直困扰着小盆友,所以顺便记录和分享下。

(1)build.gradle 最终是以什么形式存在。 (2)为什么 每个模块下的 build.gradle 文件的最开始都有 apply plugin: 'com.android.library' 这样一行代码。

自动生成完的 build.gradle 格式如下所示

apply plugin: 'com.android.library'

android {
	// 省略一些配置
}

dependencies {
	// 省略依赖
}
复制代码

这个文件最终会被转换为 org.gradle.api.Project 类(其类的关系如下图)。

  • 第一行代码的 apply 会调用 PluginAwarevoid apply(Map<String, ?> options); 方法,进行设置插件;
  • 接下来的 android,并不是 gradle 中所带的,而是第一行代码插件所带来。具体会映射为 com.android.build.gradle.AppExtension 类;
  • 最后的 dependencies,会调用 Projectvoid dependencies(Closure configureClosure); 方法;

2、defaultConfig 的存在形式

defaultConfig 会被映射为 DefaultConfig 类,其继承结构图如下

3、defaultConfig 中属性的意义

下面是官方给出的文档,我们以 3.3 的版本进行讲解,其他版本可能有些许的小改动。

defaultConfig官方文档 传送门

3.1 applicationId

  • 类型:String
  • 描述:应用的id,即我们常说的包名。我们都知道 android studio 是以 applicationId 作为包名,以前使用 eclipse 时,则另当别论了。
  • 使用方法:
defaultConfig {
    // applicationId 应用的包名
    // applicationId 会替换 AndroidManifest.xml 中的 manifest 标签下 package 的 value
    applicationId "com.zinc.gradlestudy"
	......省略其他配置
}
复制代码

3.2 applicationIdSuffix

  • 类型:String
  • 描述:会追加在上面 applicationId 字符串的后面,形成最终的包名
  • 使用方法:
defaultConfig {
	// 若此时 applicationId 为 com.zinc.gradlestudy,则最终会形成 com.zinc.gradlestudy.debug 的包名
    applicationIdSuffix "debug"
	......省略其他配置
}
复制代码

3.3 externalNativeBuild

  • 类型:ExternalNativeBuildOptions
  • 描述:这里我们设置 ndk 编译过程的一些参数。分为 cmake 和 ndkBuild 两个参数。
  • 使用方法:
defaultConfig {
    externalNativeBuild {
        ndkBuild {
            // Passes an optional argument to ndk-build.
            arguments "NDK_MODULE_PATH+=../../third_party/modules"
        }
        // For ndk-build, instead use the ndkBuild block.
        cmake {
             // Passes optional arguments to CMake.
             arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"

             // Sets a flag to enable format macro constants for the C compiler.
             cFlags "-D__STDC_FORMAT_MACROS"

             // Sets optional flags for the C++ compiler.
             cppFlags "-fexceptions", "-frtti"

             // Specifies the library and executable targets from your CMake project
             // that Gradle should build.
             targets "libexample-one", "my-executible-demo"
         }
   }
}
复制代码

cmake 具体参数 传送门
ndkBuild 具体参数 传送门

3.4 dimension

  • 类型:String
  • 描述:当前的配置所属的 “风味维度”,这个参数在这里的并没有实际的意义,在打多渠道包的时候,会进行更多的分享。
  • 使用方法:
defaultConfig {
	dimension 'debug'
	......省略其他配置
}
复制代码

3.5 consumerProguardFiles

  • 类型:List< File >
  • 描述:这个属性只作用于我们创建的 library 中,包括我们以aar形式导入的 library ,或是直接创建的 library。它的作用是,负责该 library 被进行编译时的混淆规则,我们在 主App 的模块下则可以不用再管理各个 library 的混淆规则,会直接使用各个 library 的混淆规则文件。
  • 使用方法:
defaultConfig {
	consumerProguardFiles 'consumer-rules.pro'
	......省略其他配置
}

// 因为该属性是一个 List<File> 类型,如果需要多个文件配置,则如下所示
defaultConfig {
	consumerProguardFiles 'consumer-rules.pro','zincPower-rules.pro'
	......省略其他配置
}
复制代码

3.6 javaCompileOptions

  • 类型:JavaCompileOptions
  • 描述:配置编译时 java 的一些参数,例如我们使用 annotationProcessor 时所需要的参数。
  • 使用方法:
defaultConfig {
	javaCompileOptions {
        annotationProcessorOptions{
			arguments = []
			classNames ''
			....
		}
	}
	......省略其他配置
}
复制代码

JavaCompileOptions 可以配置的具体参数,请进传送门

3.7 manifestPlaceholders

  • 类型:Map<String, Object>
  • 描述:配置可以在 AndroidManifest.xml 中替换的参数,一般用于多渠道中使用,不会在 defaultConfig 中使用。
  • 使用方法:

这里想配置我们应用的logo,则可以在 gradle 中使用下面这段

defaultConfig {
	manifestPlaceholders = [APP_LOGO_ICON: "@mipmap/ic_logo"]
}
复制代码

然后在 AndroidManifest.xml 中使用,使用 ${你配置的变量名}

// 在 application 中使用替换,还需要多添加 tools:replace 这一标签,将我们需要替换的名称写上,例如这里的 android:icon
<application
    android:allowBackup="true"
    android:icon="${APP_LOGO_ICON}"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:replace="android:icon">
......
复制代码

3.8 multiDexEnabled

64K 引用限制问题官方文档 传送门

  • 类型:Boolean
  • 描述:是否开启分包。因为安卓中方法索引值为两个字节,四位十六进制的一个数值,即[0, 0xffff],所以最大方法数为65536个。一旦超出了,就需要进行分包,所以我们就需要开启这个参数。
  • 使用方法:
defaultConfig {
	multiDexEnabled true
	...
}

// 添加依赖
dependencies {
	// 如果使用的为 AndroidX,则使用下面这个导入
	// implementation 'androidx.multidex:multidex:2.0.1'
	// 如果不使用 AndroidX,则使用下面这段
    compile 'com.android.support:multidex:1.0.3'
}
复制代码

有两种开启 MultiDex 方法:

// 第一种:让你应用的 Application 继承 MultiDexApplication。
public class MyApplication extends MultiDexApplication {

}

// 第二种:重写应用的 Application 方法 attachBaseContext
public class MyApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}
复制代码

最后别忘了在 AndroidManifest.xml 中使用我们在上面的 Application。

3.9 multiDexKeepFile

  • 类型:File
  • 描述:将我们需要的类打包进主包,即 classs.dex。我们在第 3.8 小点,分享到使用了多包处理,有时我们需要将一些主要的类打包进主包,则可以使用该属性。
  • 使用方法:
defaultConfig {
	multiDexKeepFile file('multidex-config.txt')
	...
}
复制代码

multidex-config.txt 中的书写则如下,每一个文件则为一行

com/example/MyClass.class
com/example/TestClass.class
复制代码

3.10 multiDexKeepProguard

  • 类型:File
  • 描述:将我们需要的类打包进主包,和第 3.9 点的功能相同,区别在于写法。
  • 使用方法:
defaultConfig {
	multiDexKeepFile file('multidex-config.pro')
	...
}
复制代码

multidex-config.pro 中的写法如下

// 将会保留所有的在com.example package的类
 -keep class com.example.** { *; }
复制代码

3.11 ndk

  • 类型:NdkOptions
  • 描述:用于abi过滤
  • 使用方法: 进行如下配置,编译出来的 Apk包只包含armeabi-v7a,不会包含其他的架构,例如 "X86"。
defaultConfig {
	// ndk中,目前只有 abiFilter 一个属性,所以 ndk 目前来说只用于 abi 的过滤
	ndk {
        abiFilter 'armeabi-v7a'
    }
	...
}
复制代码

NdkOptions的具体可配参数见官方文档 传送门

3.12 proguardFiles

  • 类型:List
  • 描述:配置混淆规则文件,但我们一般不会在这里使用该配置,而会在 buildTypes 中结合 minifyEnabled 一起使用。

3.12 signingConfig

  • 类型:SigningConfig
  • 描述:配置签名配置,但一般不会在这里进行配置,而会在 buildTypes 中进行配置,这里先不过多解释。

3.13 vectorDrawables

  • 类型:VectorDrawablesOptions
  • 描述:配置矢量图的参数
  • 使用方法: VectorDrawablesOptions 中只有两个参数,为 generatedDensitiesuseSupportLibrary。分别的用处如下
defaultConfig {
    vectorDrawables {
        // 如果 minSdkVersion 小于 21,只生成mdpi的png
        generatedDensities 'mdpi'

        // 设置为 true,会忽略 generatedDensities ,会加入svg兼容包,不会再产生png
        useSupportLibrary true
    }
}
复制代码

矢量图的用法,可以看小盆友的另一片文章

3.14 versionCode

  • 类型:Integer
  • 描述:应用当前的版本值。和 versionName 的区别在小盆友看来,versionCode 是给程序员看的,versionName 是给产品经理和用户看的。
  • 使用方法:
defaultConfig {
    versionCode 1000
    ......
}
复制代码

3.15 versionName

  • 类型:String
  • 描述:应用版本。我们通常所说的该应用的版本是“1.2.0”,则是由这个值配置的。
  • 使用方法:
defaultConfig {
	versionName "1.0.0"
	.....
}
复制代码

3.16 versionNameSuffix

  • 类型:String
  • 描述:追加在第 3.15 小点“版本”的后缀
  • 使用方法:
defaultConfig {
	// 如果 versionName "1.0.0" ,则最终的版本名为 1.0.0.test
	versionNameSuffix ".test"
	.....
}
复制代码

4、defaultConfig 中方法的意义

4.1 buildConfigField(type, name, value)

  • 描述:我们可以在 BuildConfig 类中添加值,最终会在 BuildConfig 中添加如下一行代码。
// 值的注意的是 value 的值是原样放置,我们通过使用方法一节来了解
<type> <name> = <value>
复制代码
  • 使用方法:
defaultConfig {
    // 可以通过 BuildConfig 进行获取
    buildConfigField('String', 'name', '"zinc"')
    buildConfigField('int', 'age', '26')
	.....
}
复制代码

最终会生成如下图的配置,我们可以通过下面代码进行获取

String name = BuildConfig.name;
int age = BuildConfig.age;
复制代码

值的一提的是,我们设置 String 类型的参数时,需要加上 "" 双引号(如例子中的name属性)。切记!

4.2 consumerProguardFile(proguardFile)

  • 描述:和上面分享的 3.5 小点的属性 consumerProguardFiles 是一样的作用。只是这里只能设置一个 混淆文件。
  • 使用方法:
defaultConfig {
	consumerProguardFile('consumer-rules.pro')
}
复制代码

4.3 consumerProguardFiles(proguardFiles)

  • 描述:和上面分享的 3.5 小点的属性 consumerProguardFiles 是一样的作用,而且也是多个混淆文件。
  • 使用方法:
defaultConfig {
	consumerProguardFile('consumer-rules.pro', 'zincPower-rules.pro',.....)
}
复制代码

4.4 maxSdkVersion(maxSdkVersion)

  • 描述:设置应用的最高支持版本,一般我们不会进行设置
  • 使用方法:
defaultConfig {
	// 最高支持28版本
	minSdkVersion 28
}
复制代码

4.5 minSdkVersion(minSdkVersion)

  • 描述:设置应用的最低支持版本
  • 使用方法:
defaultConfig {
	// 最低支持19版本
	minSdkVersion 19
}
复制代码

4.6 missingDimensionStrategy(dimension, requestedValue)

  • 相似方法:missingDimensionStrategy(dimension, requestedValues) 区别在于第二个参数可以设置多个风味。
  • 参数说明: (1)dimension:维度 (2)requestedValue:风味(如果为 requestedValues 则是风味列表)
  • 描述:忽略在 Library 中的渠道设置,即维度(dimension)和风味(flavor),如果不进行忽略,在进行引入的时候会无法进行。
  • 使用方法:

我们的项目结构如下

zinclibrarybuild.gradle 中编写了如下渠道配置

// 创建 风味维度
flavorDimensions('zinc', 'handsome')
// 创建产品风味
productFlavors {
    minApi13{
        dimension 'zinc'
    }
    minApi23{
        dimension 'zinc'
    }
    x86{
        dimension 'handsome'
    }
    arm64{
        dimension 'handsome'
    }
}
复制代码

此时如果直接在 appbuild.gradle 中添加依赖,同步时便会出错

dependencies {
	...忽略其他依赖
    implementation project(":zinclibrary")
}
复制代码

所以我们需要在 appbuild.gradle 中使用这个参数进行忽略 library 中带来的维度和风味,即使用如下代码

defaultConfig {
    missingDimensionStrategy 'zinc', 'minApi13', 'minApi23'
    missingDimensionStrategy 'handsome', 'x86', 'arm64'
}
复制代码

4.7 resConfig(config)

  • 描述:保留的资源配置。
  • 使用用法:
defaultConfig {
	// 这样我们编译出的apk中,只有 “默认” 和 “中文zh” 两种资源
	resConfig "zh"
}
复制代码

4.8 resConfigs(config)

  • 描述:保留的资源配置,和 resConfig 的区别在于,resConfigs 保留多个资源。
  • 使用用法:
defaultConfig {
	// 这样我们编译出的apk中,只有 “默认” 、 “中文zh” 和 “英文en” 两种资源
	resConfigs "zh","en"
}
复制代码

4.9 resValue(type, name, value)

  • 描述:添加 value 资源
  • 使用用法:
defaultConfig {
	// 添加至 res/value,通过 R.string.age 获取
    resValue('string', 'age', '12year')
}
复制代码

4.10 targetSdkVersion(targetSdkVersion)

  • 描述:应用的目标版本。说明我们已经对指定的版本进行了测试,在开发过程中可以使用至该版本的API,否则会被提示无法使用。如果不设置,则和 minSdkVersion 的值保持一致。
  • 使用用法:
defaultConfig {
	targetSdkVersion 28
}
复制代码

三、写在最后

Gradle 的配置文件看起来好像挺乱,其实是因为我们没有进行整体的梳理,所以这段时间,小盆友会不断的进行整理并结合在项目中用到的分享出来。如果喜欢的话请给我一个赞,并关注我吧。文章中如有写的不妥的地方,请评论区或加我微信与我讨论吧,共同进步。

欢迎加我微信,进行更多的交流

如果觉得文章有很大的帮助,快来赞赏一次吧😄

关注下面的标签,发现更多相似文章
评论