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 類(其類的關係如下圖)。

Project
ExtensionAware
PluginAware
  • 第一行代碼的 apply 會調用 PluginAwarevoid apply(Map<String, ?> options); 方法,進行設置插件;
  • 接下來的 android,並不是 gradle 中所帶的,而是第一行代碼插件所帶來。具體會映射爲 com.android.build.gradle.AppExtension 類;
  • 最後的 dependencies,會調用 Projectvoid dependencies(Closure configureClosure); 方法;

2、defaultConfig 的存在形式

defaultConfig 會被映射爲 DefaultConfig 類,其繼承結構圖如下

DefaultConfig
BaseFlavor
DefaultProductFlavor
CoreProductFlavor
BaseConfigImpl
ProductFlavor
BaseConfig
DimensionAware

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 的配置文件看起來好像挺亂,其實是因爲我們沒有進行整體的梳理,所以這段時間,小盆友會不斷的進行整理並結合在項目中用到的分享出來。如果喜歡的話請給我一個贊,並關注我吧。文章中如有寫的不妥的地方,請評論區或加我微信與我討論吧,共同進步。

歡迎加我微信,進行更多的交流

如果覺得文章有很大的幫助,快來讚賞一次吧😄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章