零散知識點總結(1) Gradle 使用配置總結

1、統一管理依賴版本

1.1 在根目錄下,新建config.gradle文件

ext {

    android = [
            compileSdkVersion: 23,
            buildToolsVersion: "23.0.3",
            applicationId: "com.example.lizejun.repogradle",
            minSdkVersion: 14,
            targetSdkVersion: 23,
            versionCode: 1,
            versionName: "1.0",
            testInstrumentationRunner: "android.support.test.runner.AndroidJUnitRunner"
    ]

    dependencies = [
            "support-v4"  : 'com.android.support:support-v4:23.2.0',
            "support-v7"  : 'com.android.support:appcompat-v7:23.2.0'
    ]

}
複製代碼

android用來管理SDK版本、版本號等,dependencies用來管理依賴庫的版本,它們都是一個數組,用逗號來分割,數組的每一個元素都是key:value的格式。java

1.2 在根目錄下的build.gradle,新增:

apply from: "config.gradle"
複製代碼

1.3 在根目錄下的各個Module或者Library中的build.gradle文件中,引用對應的key

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion
    defaultConfig {
        applicationId rootProject.ext.android.applicationId
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
        testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
    }
}

dependencies {
    compile rootProject.ext.dependencies["support-v7"]
}
複製代碼

2、查看依賴關係

2.1 工具查看

依賴樹的查看能夠經過Android Studio的插件Gradle View來查看: android

Gradle View.png
重啓以後,點擊 View -> Tool Windows -> Gradle View,以後會在最下方生成一個窗口,咱們經過這個窗口就能夠看到對應項目的依賴關係:
Gradle View Result.png

2.2 命令查看

除此以外,咱們也可使用如下的命令:windows

./gradlew -q app:dependencies
複製代碼

一樣能夠得到相似的結果: api

命令.png
注意上圖,若是標記了 (*),那麼表示這個依賴被忽略了,這是由於其餘頂級依賴中也依賴了這個傳遞的依賴, Gradle會自動分析下載最合適的依賴。

3、標識符

因爲多個頂級依賴當中,可能包含了相同的子依賴,可是它們的版本不一樣,這時候爲了選擇合適的版本,那麼就須要使用一些必要的操做符來管理子依賴。數組

3.1 Transitive

默認爲true,表示gradle自動添加子依賴項,造成一個多層樹形結構;設置爲false,則須要手動添加每一個依賴項。bash

3.1.1 統一指定Transitive

configurations.all {
    transitive = false
}

dependencies {
    compile rootProject.ext.dependencies["support-v7"]
}
複製代碼

最終獲得的結果是,能夠看到前面的子依賴項都沒有了: app

2017-02-09 15:27:38屏幕截圖.png

3.1.2 單獨指定Transitive

dependencies {
    compile ('com.android.support:appcompat-v7:23.2.0') {
        transitive = false
    }
}

複製代碼

3.2 Force

用來表示強制設置某個模塊的版本:maven

configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-v4:23.1.0'
    }
}
複製代碼

以後打印,發現其依賴的包版本變成了23.1.0ide

Force.png

3.3 exclude

該標識符用來設置不編譯指定的模塊工具

3.3.1 全局配置某個模塊

configurations {
    all *.exclude group : 'com.android.support', module: 'support-v4'
}
複製代碼

此時的依賴關係爲:

2017-02-09 15:54:02屏幕截圖.png
固然, exclude後的參數有 groupmodule,能夠分別單獨使用,會排除全部匹配項。

3.3.2 單獨給某個模塊exclude

compile ('com.android.support:appcompat-v7:23.2.0') {
        exclude group : 'com.android.support', module: 'support-v4'
    }
複製代碼

也會和上面得到相同的結果

4、版本衝突

4.1 相同配置下的版本衝突

同一配置下,某個模塊的不一樣版本同時被依賴時,默認使用最新版,Gradle同步時不會報錯。

5、Gradle詳解

基本配置:AS中的Android項目一般至少包含兩個build.gradle,一個是Project範圍的,另外一個是Module範圍的,因爲一個Project能夠有多個Module,因此每一個Module下都會對應一個build.gradle

5.1 Project下的build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle"

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.1'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
複製代碼
  • buildscript下的repositoriesgradle腳本自身須要的資源,
  • allprojects下的repositories是項目全部模塊須要的資源。

5.2 模塊的build.gradle

//聲明插件,代表這是一個Android程序;若是是庫,那麼應當是com.android.library
apply plugin: 'com.android.application'
//Android構建過程須要配置的參數
android {
    //編譯版本
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    //buildTool版本
    buildToolsVersion rootProject.ext.android.buildToolsVersion
    //默認配置,同時應用到debug和release版本上
    defaultConfig {
        applicationId rootProject.ext.android.applicationId
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
        testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
    }
    //配置debug和release版本的一些參數,例如混淆,簽名配置等
    buildTypes {
        //release版本
        release {
            minifyEnabled false //是否開啓混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //混淆文件位置
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile rootProject.ext.dependencies["support-v7"]
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    testCompile 'junit:junit:4.12'
}
複製代碼

下面對Android構建過程當中須要配置的參數作一些解釋:

  • compileSdkVersion:告訴gradle用那個Android SDK的版本編譯你的應用,修改它不會改變運行時的行爲,由於它不會被包含進入最終的APK中;所以,推薦使用最新的SDK編譯;若是使用Suppport Library,那麼compileSdkVersion必需要大於等於它的大版本號。
  • minSdkVersion:應用最低可運行的要求;它必需要大於等於你所依賴的庫的minSdkVersion
  • targetSdkVersionAndroid提供向前兼容的重要依據。(targetSdkVersion is the main way Android provides forward compatibility) 由於隨着Android系統的升級,某個api或者模塊的行爲有可能發生改變,可是爲了保證老APK的行爲和之前兼容,只要APKtargetSdkVersion不變,那麼即便這個APK安裝在新的Android系統上,那麼行爲仍是保持老的系統上的行爲。 系統在調用某個api或者模塊的時候,會先檢查調用的APKtargetSdkVersion,來決定執行什麼行爲。

minSdkVersiontargetSdkVersion最終會被包含進入最終的APK文件中,若是你查看生成的AndroidManifest.xml,那麼會發現:

<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="7" />
複製代碼

因此,咱們通常遵循的規則是:

minSdkVersion (lowest possible) <= targetSdkVersion == compileSdkVersion (latest SDK)
複製代碼

5.3 gradle相關文件

  • gradle.properties 配置文件,能夠定義一些常量供build.gradle使用,好比能夠配置簽名相關信息,例如keystore位置、密碼、keyalias等。
  • settings.gradle 用來配置多模塊的,若是你的項目有兩個模塊BrowserScannerSDK,那麼就須要:
include ':Browser'
include ':ScannerSDK'
project(':ScannerSDK').projectDir = new File(settingsDir, './ScannerSDK/')
複製代碼
  • gradle文件夾 裏面有兩個文件,gradle-wrapper.jargradle-wrapper.properties,後者當中指定了gradle的版本。
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
複製代碼
  • gradlewgradlew.bat 分別是Linuxwindows下的批處理文件,它們的做用是根據gradle-wrapper.properties文件中的distributionUrl下載對應的gradle版本,這樣即便環境沒有安裝gradle也能夠編譯。

5.4 gradle倉庫

gradle有三種倉庫:maven/ivy/flat本地

maven{
    url  "..."
}
ivy{
    url  "..."
}
flatDir{
    dirs 'xxx'
}
複製代碼

有些倉庫取了別名:

repositories{
    mavenCentral()
    jcenter()
    mavenLocal()
}
複製代碼

5.5 gradle任務

經過如下指令,能夠看到支持的任務:

./gradlew tasks
複製代碼

Task1.png

Task2.png

6、常見問題

6.1 導入本地Jar

導入單個jar文件:

compile files('libs/xxx.jar')
複製代碼

導入libs的多個jar文件:

compile fileTree(dir: 'libs', include: ['*.jar'])
複製代碼

6.2 導入maven

compile 'groupId:artifactId:version'
複製代碼

6.3 導入Project

在導入以前,須要在settings.gradle中把模塊包含進來,例如前面的ScannerSDK模塊:

compile project(':ScannerSDK')
複製代碼

6.4 聲明第三方maven

若是項目中須要的一些庫文件再也不中央倉庫中,而是在某個特定地址裏,那麼就須要在Project中的build.gradle中的allprojects結點下或者直接配到某個模塊中:

allprojects {
    repositories {
        maven {
            url '地址'
        }
    }
}
複製代碼

6.5 依賴第三方aar

compile 'com.aaa.xxx:core:1.0.1@aar'
複製代碼

6.6 將庫導出爲aar

首先,你的項目必須是一個庫項目,以後在build.gradle中進行配置:

apply plugin : 'com.android.library'
複製代碼

以後,進入到該項目中,執行gradle命令:

./gradlew assembleRelease
複製代碼

生成的aar放在/build/output/aar文件當中

6.7 引用本地aar

首先,將aar文件拷貝到對應目錄下,而後在該模塊的build.gradle中聲明flat倉庫:

repositories{
   flatDir{
      dirs '以build.gradle爲根目錄的相對路徑'
   }
}
複製代碼

以後,在dependencies結點下依賴該aar模塊:

dependencies{
    compile (name:'xxx',ext:'aar')
}
複製代碼

7、多版本打包

在此以前,咱們先了解幾個基本的概念:

  • buildTypes構建類型Android StudioGradle組件默認提供了debugrelease兩個默認配置,這裏主要用因而否須要混淆,是否調試。
  • productFlavors產品渠道,在實際發佈中,根據不一樣渠道,可能須要使用不一樣的包名,甚至是不一樣的代碼。
  • buildVaiants:每一個buildTypesproductFlavors組成一個buildvariant

以上咱們討論的buildTypesproductFlavors能夠經過每一個Module中的build.gradleandroid標籤來配置。

下面,咱們先看一下不一樣的productFlavors,分別用來支持讀取不一樣的文件和替換不一樣的字符串。

7.1 引用不一樣的代碼

咱們首先在app/src目錄下新建兩個目錄,分別對應兩個Flavor,再在其中創建相同名字的文件Constant.java,對裏面的某個常量賦予不一樣的值。

Flavor.png

  • constantFlavor1
package com.example.lizejun.repogradle;

public class Constant {
    public static final String NAME = "flavor1";
}
複製代碼
  • constantFlavor2
package com.example.lizejun.repogradle;

public class Constant {
    public static final String NAME = "flavor2";
}
複製代碼

咱們的app下的build.gradle中的android標籤下添加以下幾行代碼,讓兩個Flavor分別引用不一樣的Constant文件:

sourceSets {
        constantFlavor1 {
            java.srcDirs =  ['src/constantFlavor1', 'src/constantFlavor1/java', 'src/constantFlavor1/java/']
        }
        constantFlavor2 {
            java.srcDirs =  ['src/constantFlavor2', 'src/constantFlavor2/java', 'src/constantFlavor2/java/']
        }
    }

    productFlavors {
        constantFlavor1 {}
        constantFlavor2 {}
    }
複製代碼

以後咱們進行打包,能夠獲得如下不一樣安裝包,這兩個apk若是在其中引用的了NAME,那麼它會獲得不一樣的值:

2017-02-10 16:15:51屏幕截圖.png

7.2 自定義buildConfig

若是咱們只須要定義一些簡單的值,那麼咱們能夠用buildConfig類:

productFlavors {
        constantFlavor1 {
            buildConfigField "boolean", "BOOLEAN_VALUE", "true"
        }
        constantFlavor2 {
            buildConfigField "boolean", "BOOLEAN_VALUE", "false"
        }
    }
複製代碼

7.3 佔位符

productFlavors {
        constantFlavor1 {
            buildConfigField "boolean", "BOOLEAN_VALUE", "true"
            manifestPlaceholders = [label:"constantFlavor1"]
        }
        constantFlavor2 {
            buildConfigField "boolean", "BOOLEAN_VALUE", "false"
            manifestPlaceholders = [label:"constantFlavor2"]
        }
    }
複製代碼

以後,咱們再在AndroidManifest.xml中引用它:

android:label="${label}"
複製代碼

7.4 簽名配置

首先是在android標籤下,咱們使用signingConfigs來配置不一樣的簽名類型

signingConfigs {
        eng {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('debug.keystore')
            storePassword 'android'
        }
        prd {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('debug.keystore')
            storePassword 'android'
        }
    }
複製代碼

以後,再在buildTypes的各個分支中引用對應的簽名配置:

buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.eng
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.prd
        }
    }
複製代碼

7.5 依賴

有時候,咱們須要在不一樣的buildTypes下,引用不一樣的依賴,例如內存泄露的檢測工具,咱們但願在debug版本時檢查內存泄露,並在發生時在桌面上生成圖標,可是在release版本上咱們並不但願這麼作,這時候咱們能夠這麼寫:

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
複製代碼

這樣,release版本就不會在桌面生成內存泄露的圖標。


更多文章,歡迎訪問個人 Android 知識梳理系列:

相關文章
相關標籤/搜索