實際項目中,都會應用Android Gradle Plugin
,根據實際中的項目模塊的職責,可以具體應用如下四種插件類型。
1,apply plugin: 'com.android.application'
實際對應的原型是:com.android.build.gradle.AppExtension
,表示此項目模塊類型為Android App Module
,對應構建生成的文件為.apk
類型文件。
2,apply plugin: 'com.android.library'
實際對應的原型是:com.android.build.gradle.LibraryExtension
,表示此項目模塊類型為Android Library Module
,對應構建生成的文件為.arr
類型的文件。
3,apply plugin: 'com.android.test'
實際對應的原型是:com.android.build.gradle.TestExtension
,表示此項目模塊類型為Android test Module
,可以在單個模塊內通過targetProjectPath
指定項目,用於對應項目的單元測試。
4,apply plugin: 'com.android.feature'
實際對應的原型是:com.android.build.gradle.FeatureExtension
,表示此項目模塊類型為Android feature Module
,主要用於單個模塊內實現特性,以支持Android Instant Apps
。
其中,一般項目中最常見的是application
和library
插件類型。
項目模塊內應用了具體的Android Gradle Plugin
類型后,可以開始進行對應的配置,如最常見的如下配置項:
apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.happycorn" minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ... } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } ... } ... } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) ... } 復制代碼
此時可以按住CTRL
,通過鼠標懸浮,可以看到對應的配置原型信息。

不同的Android Gradle Plugin
插件類型,對應不同的實現原型,以及對應可能不同的對外配置項。
同樣的,跟蹤defaultConfig{}
原型信息,可以進入到如下原型說明。
/**
* Specifies defaults for variant properties that the Android plugin applies to all build * variants. * * <p>You can override any <code>defaultConfig</code> property when <a * href="https://developer.android.com/studio/build/build-variants.html#product-flavors"> * configuring product flavors</a>. * * <p>For more information about the properties you can configure in this block, see {@link * ProductFlavor}. */ public void defaultConfig(Action<DefaultConfig> action) { checkWritability(); action.execute(defaultConfig); } 復制代碼
可見,defaultConfig{}
所對應的具體職責是:
為變體屬性,指定默認值,Android plugin 可以將指定的變體屬性的默認值,應用到所有的變體中。
執行action.execute(defaultConfig);
后,將為DefaultConfig
對象指定具體的配置。
實際項目開發中,我們往往關注此處有哪些配置項,以及每個配置項對應的含義及作用。
首先可以在Android Gradle DSL
文檔上對應查詢DefaultConfig
使用說明。 具體參見: google.github.io/android-gra…
文檔中列出了DefaultConfig
對象的對外可配置的屬性、方法,以及對應說明,在具體配置時,可能有些需要注意的事項,文檔中也做了詳盡敘述。


但無論是屬性還是方法,一般在build.gradle
中配置defaultConfig{}
時,一般都是采用形如 key value
形式,當然,實際上也可以采用對應的方法原型形式配置,效果是等價的,不過有個前提是,此方法原型是確實存在的,否則,Gradle
會報錯。 如:
defaultConfig {
...
minSdkVersion 15
...
}
等價於
defaultConfig {
...
minSdkVersion(15)
...
}
復制代碼
defaultConfig{}
中配置的屬性,在構建時,會默認生成對應的變體目錄下的BuildConfig.java
文件,此文件中將之前配置的屬性轉變成了對應的JAVA
常量形式。
如build.gradle
中配置如下:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.happycorn" minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { } } flavorDimensions "default" productFlavors { demo { applicationIdSuffix "demo" } full { applicationIdSuffix "full" } } } 復制代碼
執行./gradlew assembleFull
命令,對應生成的BuildConfig
文件為:

如其中的buildType
為debug
對應的BuildConfig
文件內容為:
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.happycorn;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "com.happycorn.full"; public static final String BUILD_TYPE = "debug"; public static final String FLAVOR = "full"; public static final int VERSION_CODE = 1; public static final String VERSION_NAME = "1.0"; } 復制代碼
BuildConfig
文件為JAVA
源碼級別,構建時也會對應被編譯打包到包中,可以直接在對應的模塊中使用。
利用此特性,我們經常可以在項目中對變體環境進行邏輯判斷,對應的進行邏輯處理。 如:判斷是否是DEBUG
,對應的輸出Log
等。
if (BuildConfig.DEBUG) { Log.d(TAG, "come here..."); } 復制代碼
另外,DefaultConfig
對象中專門對外提供了buildConfigField(type, name, value)
方法,用於向構建時生成的BuildConfig.java
類中增加新的屬性。
如:defaultConfig{}
中通過buildConfigField(type, name, value)
添加如下。
defaultConfig {
...
// 是否打對對用戶的內測包
innerTest = project.hasProperty('innertest') ? innertest : 'false' buildConfigField "boolean", "INNER_TEST", innerTest // 添加模塊對應的模塊名 buildConfigField "String", "MODULE_NAME", "\"${project.name}\"" } 復制代碼
生成的BuildConfig.java
中將有對應屬性產生。
public final class BuildConfig {
...
// Fields from default config.
public static final boolean INNER_TEST = false; public static final String MODULE_NAME = "app"; } 復制代碼
利用此特性,可以很有技巧性的去處理項目中的一些特定的問題。參照上例代碼中的兩個追加的屬性。
如:
在Gradle
構建時,通過命令參數-P
傳入對應參數鍵值,可以將其在defaultConfig{}
中添加,以自動在BuildConfig.java
中生成對應屬性,然后程序中對應進行一些邏輯的特別處理。
if (BuildConfig.INNER_TEST) { // 用戶內測的一些邏輯處理 ... } 復制代碼
又如:
調用項目日志系統時,可以傳入對應的模塊名,以實現對各個模塊的日志過濾展示等。 此時就可以通過project.name
取到模塊名,追加到BuildConfig.java
中。然后調用日志庫時可以取用。
CLog.e(BuildConfig.MODULE_NAME, TAG, e)
復制代碼
更進一步,此處對各個模塊通過defaultConfig{}
配置向BuildConfig.java
中追加屬性可以寫成:
allprojects {
...
afterEvaluate { project ->
def android = project.extensions.findByName("android") if(android != null){ def defaultConfig = android["defaultConfig"] defaultConfig.buildConfigField("String", "MODULE_NAME", "\"${project.name}\"") } } } 復制代碼
使得整體用法顯得非常靈活。
除了buildConfigField(type, name, value)
方法外,還有一個實用方法resValue(String type, String name, String value)
。
resValue(String type, String name, String value)
等價於向模塊res/values
中新增一個資源。
如:在buildType
為debug
中新增資源:
buildTypes {
release {
minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { resValue("string", "app_name_debug", "HappyCornDebug") resValue("integer", "token", "365") } } 復制代碼
編譯后,對應變體目錄結構下會生成資源文件,及對應的資源鍵值。

項目中對應需要的此資源的地方也可以直接取用:
getResources().getString(R.string.app_name_debug);
getResources().getInteger(R.integer.token);
復制代碼
當defaultConfig{}
中配置的屬性與productFlavors
中具體Flavor
中配置的屬性重復時,Android Gradle
構建時將以productFlavors
中的對應配置為准,可以理解成將defaultConfig{}
中對應的配置覆蓋掉了。但applicationIdSuffix
除外(applicationIdSuffix
依然是追加的形式)。
在現實的項目需求中,外部傳入的參數鍵值或通過Gradle/Android Gradle
腳本獲取的值,結合defaultConfig{}
配置,變體,以及對應生成的BuildConfig.java
或資源文件,實現一些特定場景下的需求,整體可以非常靈活,且具有一定的技巧性。
作者:HappyCorn
鏈接:https://juejin.im/post/5c70a1f56fb9a04a0e2dd008
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。