1. 程式人生 > >Android Studio Gradle 進階設定

Android Studio Gradle 進階設定

前言

一直想總結一些常用的 gradle 的用法,省的每次都要查閱,也方便自己複習和備忘。ps:最近也看到了一篇關於高效閱讀方法的文章,產生些許共鳴,也推薦給感興趣的人閱讀一下,沒準你也會喜歡!^_^

設定 Java 版本

如果想在某個 module 設定,可以在其 build.gradle 中配置:

android {
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果想要做全域性配置,那麼就在根目錄的 build.gradle 中配置:

allprojects {
  repositories {
    jcenter()
  }
  tasks.withType(JavaCompile) {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

全域性設定編碼

allprojects {
    repositories {
        jcenter()
    }
    tasks.withType(JavaCompile) {
        options.encoding
= "UTF-8" } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

定義全域性變數

先在 project 根目錄下的 build.gradle 定義全域性變數:

ext {
    minSdkVersion = 16
    targetSdkVersion = 24
}
  • 1
  • 2
  • 3
  • 4

然後在各 module 的 build.gradle 中可以通過rootProject.ext來引用:

android {
    defaultConfig {
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext
.targetSdkVersion }
  • 1
  • 2
  • 3
  • 4
  • 5

定義區域性變數

有時候一個庫會被引用多次,或者一個庫有多個依賴,但這些依賴的版本都是統一的。我們通過ext來定義一些變數,這樣在用到的時候就可以統一使用了。

ext {
    leakcanaryVersion = '1.3.1'
    scalpelVersion = "1.1.2" // other param
}
  • 1
  • 2
  • 3
  • 4
debugCompile "com.squareup.leakcanary:leakcanary-android:$leakcanaryVersion"
releaseCompile "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanaryVersion"
  • 1
  • 2

exlude關鍵字

我們經常會遇到庫衝突的問題,這個在多個部門協作的大公司會更常見到。將衝突的庫通過exclude來做剔除是一個好方法。

  1. 剔除整個組織的庫

compile ('com.facebook.fresco:animated-webp:0.13.0') {
exclude group: 'com.android.support' // 僅僅寫組織名稱
}
  • 1
  • 2
  • 3
  • 剔除某個庫

  • compile('com.android.support:appcompat-v7:23.2.0') {
        exclude group: 'com.android.support', module: 'support-annotations' // 寫全稱
        exclude group: 'com.android.support', module: 'support-compat'
        exclude group: 'com.android.support', module: 'support-v4'
        exclude group: 'com.android.support', module: 'support-vector-drawable'
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    引用本地aar

    1. 把aar檔案放在某目錄內,比如就放在某個 module 的 libs 目錄內
    2. 在這個 module 的 build.gradle 檔案中新增:

    repositories {
    flatDir {
        dirs 'libs' //this way we can find the .aar file in libs folder
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
  • 之後在其他專案中新增下面的程式碼後就引用了該 aar

  • dependencies {
    compile(name:'aar的名字(不用加字尾)', ext:'aar')
    }
    • 1
    • 2
    • 3

    如果你希望把 aar 放在專案的根目錄中,也可以參考上面的配置方案。在根目錄的build.gradle中寫上:

    allprojects {
       repositories {
          jcenter()
          flatDir {
            dirs 'libs'
          }
       }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    依賴專案中的 module 和 jar

    工程可以依賴自身的module和jar檔案,依賴方式如下:

    dependencies {
        compile project(':mylibraryModule')
        compile files('libs/sdk-1.1.jar')
    }
    • 1
    • 2
    • 3
    • 4

    配置獨立的簽名信息

    通常我們可以直接把簽名的明文資訊寫在 gradle 配置檔案中,但是在開原始碼的時候不是很方便,前者可能存放簽名檔案的位置需要修改,後者則希望隱藏簽名信息,在看不少開源專案的時候,發現很多是這樣做的 signingConfigs 位置, android 的下一級

    signingConfigs {
      release {
        storeFile file(RELEASE_STORE_FILE)
        storePassword RELEASE_STORE_PASSWORD
        keyAlias RELEASE_KEY_ALIAS
        keyPassword RELEASE_KEY_PASSWORD
      }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在對應位置引用常量,在 properties 中再進行具體賦值,這樣不會直接暴露簽名信息,也方便配置 在 gradle.properties 中

    RELEASE_KEY_PASSWORD=xxxx
    RELEASE_KEY_ALIAS=xxx
    RELEASE_STORE_PASSWORD=xxx
    RELEASE_STORE_FILE=../.keystore/xxx.jks
    • 1
    • 2
    • 3
    • 4

    多渠道打包

    在 product flavor 下定義不同型別, 把 AndroiManifest 中的 channel 替換

    productFlavors 位置: android 的下一級

    android {
      productFlavors {
        fir {
          manifestPlaceholders = [UMENG_CHANNEL_VALUE: "fir"]
    
        }
        GooglePlay {
          manifestPlaceholders = [UMENG_CHANNEL_VALUE: "GooglePlay"]
        }
        Umeng {
          manifestPlaceholders = [UMENG_CHANNEL_VALUE: "Umeng"]
        }
      }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    替換 AndroiManifest 中的欄位

    <meta-data
        android:name="UMENG_CHANNEL"
        android:value="${UMENG_CHANNEL_VALUE}"/>
    • 1
    • 2
    • 3

    減少編譯錯誤和忽略 lint 檢查

    packagingOptions {
      exclude 'META-INF/DEPENDENCIES.txt'
      exclude 'META-INF/LICENSE.txt'
      exclude 'META-INF/NOTICE.txt'
      exclude 'META-INF/NOTICE'
      exclude 'META-INF/LICENSE'
      exclude 'META-INF/DEPENDENCIES'
      exclude 'META-INF/notice.txt'
      exclude 'META-INF/license.txt'
      exclude 'META-INF/dependencies.txt'
      exclude 'META-INF/LGPL2.1'
    }
    
    lintOptions {
      abortOnError false
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    生成自定義 App 名稱

    //生成自定義App名稱
    def generateAppName(variant) {
        variant.outputs.each { output ->
            def file = output.outputFile
            output.outputFile = new File(file.parent, "Gank.IO-V" +           android.defaultConfig.versionName + ".apk")
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    指定資源目錄

    自定義 java 程式碼和 res 資源的目錄,更加靈活

    android {
        sourceSets {
            main {
                manifest.srcFile 'AndroidManifest.xml'
                java.srcDirs = ['src']
                resources.srcDirs = ['src']
                aidl.srcDirs = ['src']
                renderscript.srcDirs = ['src']
                assets.srcDirs = ['assets']
                if (!IS_USE_DATABINDING) { // 如果用了databinding
                    jniLibs.srcDirs = ['libs']
                    res.srcDirs = ['res', 'res-vm'] // 多加了databinding的資源目錄
                } else {
                    res.srcDirs = ['res']
                }
            }
    
            test {
                java.srcDirs = ['test']
            }
    
            androidTest {
                java.srcDirs = ['androidTest']
            }
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在 BuildConfig.class 中增加靜態變數

    有時候我們想根據不同的版本,設定相同變數不同的值,最常見的使用場景就是 Log 工具類,通過設定 isDubug 不同值,只有 debug 版本的 app 會產生 log 日誌,設定過程如下:

     buildTypes {
            release {
                buildConfigField("boolean", "isDebug", "false") // 定義 isdubug 的值
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
    
            debug{
                buildConfigField("boolean", "isDebug", "true")
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在 sync 後BuildConfig中就有你定義的這個變數(isDebug)。

    public final class BuildConfig {
      public static final boolean DEBUG = Boolean.parseBoolean("true");
      public static final String APPLICATION_ID = "com.hiwhitley.himei";
      public static final String BUILD_TYPE = "debug";
      public static final String FLAVOR = "";
      public static final int VERSION_CODE = 1;
      public static final String VERSION_NAME = "1.0";
      // Fields from build type: debug
      public static final boolean isDebug = true;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果有帶引號的 string,要記得轉義:

    buildConfigField "String", "URL_ENDPOINT", "\"http://your.development.endpoint.com/\""
    • 1

    結語

    此外,gralde 設定可以結合 AndroidStudio 提供的圖形介面設定,理解會更快更透徹 File-Project Structure-Modules-app

    img

    參考