Android Gradle使用總結(2)

Android Gradle使用篇:

Android Gradle使用總結(1)

Android Gradle使用總結(2)

1、自定義Android gradle工程

一、defaultConfig默認配置

defaultConfig 是默認的配置,是一個ProductFlavour。對於多渠道打包,等狀況,若是不針對自定義的是一個ProductFlavour單獨配置的話,則默認使用defaultConfig的配置java

(1)applicationId

指定生成的app包名,對應值是 String,如:applicationId "com.android.xx"android

(2)minSdkVersion

App最低支持的Android操做系統版本,對應值是 int型(即對於sdk 的ApiLevel)如,minSdkVersion 25git

(3)targetSdkVersion

配置當前是基於哪一個sdk版本進行開發,可選值與 minSdkVersion同樣bash

(4)versionCode

內部版本號,對應值是int型,用於配置Android App內部版本號,一般用於版本的升級架構

(5)versionName

用於配置app的版本名稱,對應值是String,如"v1.0.0",讓用戶知道當前app版本。versionCode是內部使用,versionName是外部使用,一塊兒配合完成app的版本升級控制。app

(6)testApplicationId

配置測試app的包名,默認是 applicationId + ".test",通常狀況下,用默認的便可。ide

(7)testInstrumentationRunner

用於配置單元測試時使用的Runner,默認使用android.test.InstrumentationTestRunner。工具

(8)signingConfig

配置默認的簽名信息,對生成的app進行簽名。對應值是SigningConfig對象。 具體使用,查看配置簽名信息部分post

(9)proguardFile 和 proguardFiles

二者都是配置混淆規則文件,區別是proguardFile接受一個文件對象,而proguardFiles能夠同時接受多個。單元測試

(10)multiDexEnabled

是否啓動自動拆分多個Dex的功能,用於突破方法超過65535的設置,後面再具體介紹

multiDexEnabled true

二、配置簽名信息

Android Gradle 提供了signingConfigs{}配置塊,用於生成多個簽名配置信息,其類型是NamedDomainObjectContainer,所以,咱們在signingConfigs{}中定義的都是一個SigningConfig的對象實例。

一個SigningConfig,即簽名配置,可配置的元素有:storeFile: 簽名文件位置;storeType:簽名證書類型(可不填);storePassword:簽名證書密碼;keyAlias:簽名證書密鑰別名;keyPassword:簽名證書中的密鑰的密碼。如:

signingConfigs{
        release{ //生成了release的簽名配置
            storeFile file('../John.jks')
            storePassword '12345678'
            keyAlias 'key0'
            keyPassword '12345678'
        }
    }
複製代碼

注:debug簽名文件通常位於$HOME/.android/debug.keystore

對於生成的簽名配置,能夠應用到 defaultConfig中的signingConfig進行默認簽名配置或應用到buildTypes中針對構建類型進行簽名配置。如:

buildTypes {
        release {
            signingConfig signingConfigs.release //配置release類型簽名
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    
    defaultConfig {
        applicationId "com.example.john.tapeview"
        minSdkVersion 24
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        signingConfig signingConfigs.release  //配置默認簽名
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
複製代碼

三、構建類型(buildTypes)

buildTypes{}signingConfigs{}同樣,都是Android 的一個方法,接收到也是域對象 NamedDomainObjectContainer,添加的每個都是BuildType類型。

每個BuildType都會生成一個SourceSet,默認位置是src//,所以,能夠單獨爲其指定Java源代碼和res資源等。且,新增的BuildType不能命名爲 main 或 androidTest(因android默認已經生成),且相互之間不能同名。

(1)applicationIdSuffix

用於配置基於applicationId的後綴,如applicationId爲 com.John.gradle.sample , 在debug的buildType中指定 applicationIdSuffix ".debug",則生成的debug的包名爲com.John.gradle.sample.debug。

注:library 工程不支持

(2)signingConfig

配置簽名信息,使用同前面提到的 defaultConfig同樣。

(3)啓動zipAlign優化

zipalign是android提供的整理優化apk的工具,能提升系統和應用的運行效率,更快讀寫apk資源,下降內存,因此,對於發佈的apk,通常開啓 zipAlignEnabled true //true爲開啓

(4)資源清理shrinkResources

用於配置是否自動清理未使用的資源,true爲開啓,false爲關閉。需結合混淆使用。

(5)使用混淆 minifyEnabled

啓用混淆能夠優化代碼,同時結合shrinkResources清理資源,能夠縮小apk包,還能夠混淆代碼。通常發佈的都是要混淆的。

開啓混淆:minifyEnabled true //true爲開啓;使用proguardFileproguardFiles設置混淆規則文件,二者區別如前面defaultConfig中說明。

**注:**對於多渠道打包,每一個productFlavor均可以單獨配置混淆規則文件(經過各自的proguardFileproguardFiles)。

(6)multiDexEnabled

是否啓動自動拆分多個Dex的功能,用於突破方法超過65535的設置,後面再具體介紹

multiDexEnabled true

(7)debuggable 和 jniDebuggable

debuggable:是否生成一個可供調試的apk,對應值爲boolean類型;

jniDebuggable:是否生成一個可供調試Jni(C/C++)代碼的apk,對應值爲boolean類型;

2、Android gradle高級自定義

一、批量修改生成的apk文件名

Android Gradle提供了3個屬性,applicationVariants(僅僅適用於Android 應用Gradle插件),和libraryVariants(僅僅適用於Android庫gradle插件),testVariants(以上兩種都適用)

applicationVariants是一個集合,每個元素都是一個生成的產物,即 xxxRelease 和 xxxDebug 等(即生成apk) ,它有一個outputs做爲輸出集合。遍歷,若名字以.apk結尾,那麼就是要修改的apk輸出。

//動態改變生成的apk的名字: 項目名_渠道名_v版本名_構建日期.apk
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            if (output.outputFile != null && output.outputFile.name.endsWith('.apk')
                    &&'release'==(variant.buildType.name)) {
                def flavorName = variant.flavorName.startsWith("_") ? variant.flavorName.substring(1) : variant.flavorName
                def apkFileName = "Example92_${flavorName}_v${variant.versionName}_${buildTime()}.apk"
                outputFileName = apkFileName
            }
        }
    }
    
    ...
    def static buildTime() {
    def date = new Date()
    def formattedDate = date.format('yyyyMMdd')
    return formattedDate
}
複製代碼

二、多方式配置 VersionCode 和 VersionName

(1)經過應用腳本插件(apply from)

  1. 新建一個version.gradle(當前存放在項目路徑下的gradle文件夾中),並設置自定義屬性

ext{
    appVersionCode = 1
    appVersionName = '1.0.2'
}
複製代碼
  1. 在rootProject中應用該腳本文件
apply from : 'gradle/version.gradle'
複製代碼
  1. 可在任意子工程中引用該設置:

(2)直接在屬性文件(xxx.properties)中定義使用

  1. 在工程目錄下的gradle.properties中定義
    3.可在任意子工程中引用該設置:

(3)從 git 的 tag 上獲取 VersionName 和 versionCode

/**
 * 以git tag的數量做爲其版本號
 * @return tag的數量
 */
def static getAppVersionCode(){
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'git','tag','--list'
        standardOutput = stdout
    }
    return stdout.toString().split("\n").size()
}

/**
 * 從git tag中獲取應用的版本名稱
 * @return git tag的名稱
 */
def static getAppVersionName(){
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'git','describe','--abbrev=0','--tags'
        standardOutput = stdout
    }
    return stdout.toString().replaceAll("\n","")
}
複製代碼

三、動態配置AndroidManifest文件

在構建過程,動態修改AndroidManifest文件中的內容

android gradle 提供了很是便捷的方法替換AndroidManifest文件中的內容,即manifestPlaceholder、Manifest佔位符。

manifestPlaceholdersProductFlavor的一個屬性,Map類型,因此能夠同時配置多個佔位符。

  1. 定義佔位符:
...

productFlavors{
    google{
        manifestPlaceholders.put("UMENG_CHANNEL","google")
    }
    baidu{
        manifestPlaceholders.put("UMENG_CHANNEL","baidu")
    }
}

...
複製代碼
  1. 在AndroidManifes中使用這個佔位符 "UMENG_CHANNEL"
...
<application>
    ...
    <meta-data android:value="${UMENG_CHANNEL}" android:name = "UMENG_CHANNEL"/>
    ...
</application>
...
複製代碼
  1. 亦能夠迭代修改佔位符
...
productFlavors{
        google{
        }
        baidu{
        }
    }
productFlavors.all{flavor->
    manifestPlaceholders.put("UMENG_CHANNEL",flavor.name)
}
...
複製代碼

四、自定義BuildConfig

Android gradle提供了buildConfigField(Srting type,String name ,String value) 來實現添加常量到BuildConfig中。通常在productFlavorsbuildTypes中使用:

注:對於value是String類型的,雙引號必定得加上,這裏寫了什麼,buildConfig會原封不動放上去

...
productFlavors{
        google{
            //對於value是String類型的,雙引號必定得加上,這裏寫了什麼,buildConfig會原封不動放上去
            buildConfigField 'String','name','"google"'
        }
        baidu{
            buildConfigField 'String','name','"baidu"'
        }
}
...
複製代碼

五、動態添加自定義的資源

Android gradle提供了resValue(String type,String name,String value)來 添加資源。只能在productFlavorsbuildTypes中使用

注:這裏寫了什麼,編譯出來後也會原封不動放上去

六、Dex選項配置

android {
    ...
    
    dexOptions {
        incremental true //android studio3.x以上已廢棄,是否開啓dx增量模式
        javaMaxHeapSize '4g' //提升java執行dx命令時的最大分配內存
        jumboMode true //強制開啓jumboMode模式,讓方法超過65535也構建成功
        pre
    }
    
    ...
}

複製代碼

七、編譯選項和adb操做選項

android {
    ...
    
    compileOptions {
        encoding = 'utf-8'
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    adbOptions{
      timeOutInMs = 5000 //設置超時時間,單位 ms
      installOptions '-r','-s'//安裝選項,通常不使用
    }
    
    ...
}

複製代碼

八、突破方法超過65535的限制

  1. defaultConfigbuildTypesproductFlavors中,開啓multiDexEnabledmultiDexEnabled true

  2. 增長依賴:implementation 'com.android.support:multidex:1.0.3'

  3. 在自定義的 Application 中設置(5.0以上自然支持):

使自定義的Application繼承MultiDexApplication

或直接在java代碼中修改:

...
@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}
...
複製代碼

多渠道構建

一個構建產物(apk),即Build Variant = BuildType + ProductFlavor,其中ProductFlavor又進一步劃分dimensions,即Build Variant = BuildType + ProductFlavor's dimensions

一、多渠道構建ProductFlavor屬性

...
productFlavors{
        google{
            applicationId "com.john.xxx"
        }
}
...
複製代碼

(1)applicationId,跟前面所述同樣。

(2)manifestPlaceholders,跟前面所述同樣。

(3)multiDexEnabled,跟前面所述同樣。

(4)proguardFiles,跟前面所述同樣。

(5)signingConfig,跟前面所述同樣。

(6)testApplicationId,跟前面所述同樣。

(7)versionCode 和 versionName,跟前面所述同樣。

(8)dimension

做爲ProductFlavor的維度,可理解爲ProductFlavor的分組

如,free 和 paid 屬於version分組,而x86 和 arm屬於架構分組:

android{
    ...
    
    flavorDimensions "version","abi" //定義分組
    productFlavors{
        free{
            dimension 'version'
        }
        paid{
            dimension 'version'
        }
        x86{
            dimension 'abi'
        }
        arm{
            dimension 'abi'
        }
    }
    ...
}
複製代碼

對於以上的設置,Build Variant = BuildType + ProductFlavor's dimensions,則生成的assemble任務, 即variant:

  • ArmFreeDebug
  • ArmFreeRelaese
  • ArmPaidDebug
  • ArmPaidRelease
  • X86FreeDebug
  • X86FreeRelaese
  • X86PaidDebug
  • X86PaidRelease

參考連接

Android Developer官網

相關文章
相關標籤/搜索