Gradle For Android(三)Gradle優化與靈活的使用技巧

傻小孩b發表於2016-10-24

《Gradle For Android(三)Gradle優化與靈活的使用技巧 》
轉載請註明來自傻小孩bgold.xitu.io/user/57e089…喜歡的可以關注我,不定期總結文章!您的支援是我的動力哈!

Gradle For Android 導讀

前面兩篇記錄了Gradle基礎依賴、多渠道打包以及簽名配置,對於各位程式猿來說,應該再熟悉不過了~在開發路上,依然要好好對自己的知識作為總結,今天這一篇依然是講述日常開發中gradle中的應用以及在某些場景的使用技巧。

目錄

1、善用佔位符
2、善用BuildConfig
3、保護資訊保安,方便的全域性設定
4、使用gradle.properties
5、常見配置

一、善用用佔位符

上一篇在進行多渠道打包的時候,我們說過可以根據渠道不同,個性定製不同包名的apk。然後現在會有一個問題,在我們使用第三方平臺,是必須根據包名與簽名資訊申請得到appkey,例如典型的地圖開發appkey、友盟appkey,這些我們需要在AndroidManifest中配置meta-data,例如以下程式碼:

<meta-data
           android:name="UMENG_CHANNEL"
           android:value="dwqirhqifaosfjaofq2dasda" />複製程式碼

如果是這種固定的寫法,當然不能解決我們根本的問題。因此我們需要根據渠道動態去修改這個value。Gradle元件提供了一個不錯的功能,佔位符,可以在gradle進行動態設定,舉例:

  //在渠道配置中...
       xiaomi { //小米渠道
            applicationId 'com.yuan.agradle1'//個性定製,小米市場包名不同

            // 小米渠道配置appkey
                manifestPlaceholders = [UMENG_CHANNEL_VALUE: 'xiaomi_appkey']
        }
        googlepaly { //google play 渠道
            applicationId 'com.yuan.agradle2'

            // googlepaly渠道配置appkey
               manifestPlaceholders = [UMENG_CHANNEL_VALUE: 'googlepaly_appkey'        
        }複製程式碼

當然我們也可以一次性設定,例如如下:

productFlavors.all { flavor ->
               manifestPlaceholders.put("UMENG_CHANNEL_VALUE","all_appkey")
           }複製程式碼

二、善用BuildConfig

BuildConfig,是在我們module中的build.gradle配置正確,編譯成功後,自動生成的配置檔案,一般預設為一下程式碼;

package com.yuan.agradle;

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.yuan.agradle4";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "baidu";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
}複製程式碼

BuildConfig.java無法手動進行編譯,但是他由Gradle進行動態控制。因此在作為app對Gradle的配置起到一個開關的重要作用。首先這裡有兩個關鍵欄位:1.buildConfigField 2.resValue。
首先向看下配置的程式碼:

  buildTypes {//表示構建型別 一般有release debug 兩種

        debug{
            buildConfigField 'String','STATE_TEST','"debug"'/ildConfigField
            resValue "string", "test_value", "AGradle_debug"//resValue
        }

        release { //release型別
            minifyEnabled false
            // 啟用混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            buildConfigField 'String','STATE_TEST','"release"' /ildConfigField
            resValue "string", "test_value", "AGradle_release" //resValue
        }

    }複製程式碼

1、buildConfigField
buildConfigField 這個會根據gradle的配置,在原來預設的BuildConfig.java基礎上,動態新增一個指定資料型別的value。當然,在程式中也是可以訪問到的。使用的 規則

buildConfigField 一共有3個引數,第一個是資料型別,就是你定義的常量值是一個什麼型別,和Java的型別是對等的,這裡是String。第二個引數是常量名,這裡是 STATE_TEST。第三個引數是常量值。如此定義之後,就會在BuildConfig.java中生成一個常量名為 STATE_TEST的常量定義。預設配置的生成是:

  buildConfigField 'String','STATE_TEST','"release"' /ildConfigField複製程式碼

BuildConfig.java 生成截圖為:

Gradle  For Android(三)Gradle優化與靈活的使用技巧
buildconfig_1.png

2、resValue
buildConfigField主要改變了java常量,那麼我們如何通過gradle動態配置管理資原始檔,答案是肯定的。Gradle元件提供了resValue欄位,用於動態生成value資源,在程式中也可以訪問到,其中生成的目標存在generated.xml中,使用的規則與buildConfigField 類似,即型別+常量名+常量值,例如以下程式碼:

resValue "string", "test_value", "AGradle_release" //resValue複製程式碼

generated.xml生成截圖:

Gradle  For Android(三)Gradle優化與靈活的使用技巧
Paste_Image.png

執行情況:
1、debug版本執行

Gradle  For Android(三)Gradle優化與靈活的使用技巧
debug_1.png

2、release版本執行

Gradle  For Android(三)Gradle優化與靈活的使用技巧
release_1.png

三、保護資訊保安,方便的全域性設定

在開發編譯過程中,我們需要儘可能保證一些敏感性的文字資訊保安,例如appkey、簽名資訊等。如今都比較推薦持續化構建,免去了程式猿處理編譯打包的工作,一來能讓程式猿更加專注開發、而來方便測試除錯。例如目前流行的travis、jenkins等持續化構建環境。對於資訊保安,很大程度簽名密碼等敏感資訊由CI服務進行配置,而非純文字憑證,這裡CI我後期再說明,現在先講述下全域性設定。

1、新建一個全域性配置的com_cfg.gradle,裡面的內容為如下:

// 通用配置
ext {
    // android
    BUILD_SDK_VERSION = 23
    BUILD_TOOLS_VERSION  =  "23.0.2"

    //build config
    MIN_SDK_VERSION  =  18
    TARGT_SDK_VERSION  = 24
    VERSION_CODE = 1
    VERSION_NAME = "1.0"

    //siging 這種不推薦喔
    KEY_ALIAS = 'yuan'
    KEY_PASSWORD = '888888'
    KEY_FILEPATH = "../agradle.jks"
    KEY_STORE_PASSWORD = '888888'

    //appket
    UMENG_CHANNEL_VALUE_XIAOMI =  'xiaomi_appkey'
    UMENG_CHANNEL_VALUE_GOOGLE = 'googlepaly_appkey'
}複製程式碼

2、在project的build.gradle應用這個gradle配置

apply from: 'com_cfg.gradle'複製程式碼

3、application中的build.gradle使用ext中的自定義常量,例如:

    compileSdkVersion BUILD_SDK_VERSION //SDK編譯版本
    buildToolsVersion  BUILD_TOOLS_VERSION//構建工具版本 對應buildTool

    defaultConfig {
        applicationId "com.yuan.agradle" //配置包名
        minSdkVersion MIN_SDK_VERSION // 最小支援sdk版本
        targetSdkVersion  TARGT_SDK_VERSION // 目標sdk版本
        versionCode VERSION_CODE//版本號
        versionName  VERSION_NAME //版本名稱

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }複製程式碼

Ci伺服器也是這種模式,通過終端命令列的形式將對於定義的常量,在gradle裡面進行替換操作。這樣全域性設定有一個好處,假設project裡面存在多個application module,這時候如果採用這種全域性配置,可以達到一改應用多出的效果。當然,如果你有部分library module是想釋出到jcenter,這時候可以定義一個針對library的配置檔案,只需要要在library裡面進行apply,這個可以完成獨立的配置。不僅不會讓本身的module更加笨重,並且配置會更清晰!

四、使用gradle.properties

這個跟第三個使用全域性的gradle作用有點相似,區別就是全域性的gradle是定義了ext,而gradle.properties則是直接提供配置引數。不過用法有點去吧喔,下面舉例:

1、新建gradle.properties,並且寫入一些配置引數

// android
BUILD_SDK_VERSION = 23
BUILD_TOOLS_VERSION  =  23.0.2

//build config
MIN_SDK_VERSION  =  18
TARGT_SDK_VERSION  = 24
VERSION_CODE = 1
VERSION_NAME = 1.0複製程式碼

2、module使用以及注意事項

    ////編譯版本///////////////////////////////////////////////////////////////////////////////

    compileSdkVersion BUILD_SDK_VERSION as int //SDK編譯版本
    buildToolsVersion  BUILD_TOOLS_VERSION//構建工具版本 對應buildTool

    /////編譯配置//////////////////////////////////////////////////////////////////////////////

    defaultConfig {
        applicationId "com.yuan.agradle" //配置包名
        minSdkVersion MIN_SDK_VERSION as int // 最小支援sdk版本
        targetSdkVersion  TARGT_SDK_VERSION as int// 目標sdk版本
        versionCode VERSION_CODE as int//版本號
        versionName  VERSION_NAME //版本名稱

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }複製程式碼

很明顯們看到了as int 關鍵字,這是因為本來gradle.properties配置資訊是字串的格式,如果我們輸入的常量是整形的時候,我們必須通過as int 進行型別轉化

五、常見配置

1、dexOptions

在Gradle 進行dex的可能會遇到記憶體不夠用的情況,錯誤資訊大概是java.lang.OutOfMemoryError: GC overhead limit exceeded。這個時候只需要配置dexOptions的javaMaxHeapSize大小即可:

dexOptions {  javaMaxHeapSize "2g" }複製程式碼

2、Java Compilation options

指定jdk版本,影響所有task編譯Java原始碼

android {
        compileOptions {
            sourceCompatibility = "1.7" //JavaVersion.VERSION_1_7
            targetCompatibility = "1.7" //JavaVersion.VERSION_1_7
        }
    }複製程式碼

3、aapt options,影響所有使用aapt的task

android {     
    aaptOptions {    
            noCompress 'foo', 'bar'      
            ignoreAssetsPattern "!.svn:!.git:!.ds_store:!*.scc:.*:_*:!CVS:!thumbs.db:!picasa.ini:!*~"   
                }   
            }複製程式碼

4、lintOptions

程式在buid的時候,會執行lint檢查,有任何的錯誤或者警告提示,都會終止構建,可以控制。

lintOptions {
    abortOnError false
}複製程式碼

希望對有些開發者有幫助~具體檢視可以github上的demo,也歡迎加入開發交流群哈,詳情看個人簡介。下一篇是對gradle的混淆說明,歡迎讀者閱讀~

DEMO

Gradle For Android(三)Gradle優化與靈活的使用技巧

傻小孩b mark共勉,寫給在成長路上奮鬥的你

相關文章