要點提煉| Gradle指南

在使用Android Studio過程中沒少被Gradle坑過,雖然網上有很多簡單粗暴的解決方案,但極少會說清楚緣由,所以一直想看一本叫《Android Gradle權威指南》。
不過由於書中實踐內容很多,更像一本工具書,而且Gradle現已發行了好幾版,因此本篇僅僅是陳列出一些大的要點,尤其是那些熟悉又陌生的名詞,如果想要具體瞭解細節和操作流程,一定要跟着書探索喲~

  • Gradle入門
  • Groovy基礎
  • Gradle構建腳本基礎
  • Gradle插件
  • Java Gradle插件
  • Android Gradle插件

一.Gradle入門

1.本書環境

  • JDK:OpenJDK 1.8.0
  • Gradle:Gradle 2.14.1 All 版
  • IDE:Android Studio 2.2.3
  • Android Plugin:Android Gradle 2.2.3
  • Android:API 23

2.Eclipse和Android Studio

a.開發配置區別

  • Eclipse+ADT+Ant
  • Android Studio+Gradle:Gradle比Ant更靈活,有效提高開發效率

b.Eclipse遷移到AndroidStudio兩種方式

  • 使用AndroidStudio直接導入Eclipse工程
    • 特點:使用AS默認推薦目錄結構
  • 使用Eclipse導出Android Gradle配置文件,並轉換成Gradle工程,再使用Android Studio把它作爲Gradle工程導入
    • 特點:保留原項目結構

3.Gradle的ZIP解壓後目錄

  • docs:API、 DSL、指南等文檔
  • init.d:gradle初始化腳本目錄
  • lib:相關庫
  • media:一些icon資源
  • samples:示例
  • src:源文件
  • getting-started.html:入門鏈接
  • LICENSE
  • NOTICE

4.引例:Gradle版Hello World

//build.gradle:
    task hello{//定義一個任務Task名爲hello
        doLast{//添加一個動作Action,表示在Task執行完畢後回調doLast閉包中的代碼
            println'Hello World'//輸出字符串,單雙號均可
        }
    }
//終端:
    gradle hello//執行build.gradle中名爲Hello的任務
//輸出:
    Hello World

5.Gradle Wrapper

a.含義:對Gradle一層包裝,便於使用統一Gradle構建

b.目錄結構:

|--gradle
|   |--wrapper
|        |--gradle-wrapper.jar
|        |--gradle-wrapper.properties
|--gradlew
|--gradlew.bat

  • gradle-wrapper.jar:具體業務邏輯實現的jar包
  • gradle-wrapper.properties:配置文件,包含篇配置信息如下圖:
  • gradlew:Linux下可執行腳本
  • gradlew.bat:Windows下可執行腳本

c.常用命令

  • 生成:gradle wrapper,由Wrapper Task生成
  • 配置參數:
    • gradle wrapper --gradle-version XXX用於指定使用的Gradle版本
    • gradle wrapper --distribution-url XXX用於指定下載Gradle發行版的url地址
  • 自定義:task wrapper(type:Wrapper){ //配置信息 }

6.Gradle日誌

a.日誌級別

b.日誌輸出代碼

  • 使用print方法,屬於quiet級別日誌:println 'XX'X
  • 使用內置logger:

    c.日誌輸出控制

    例如,輸出QUIET級別及其之上的日誌信息:gradle -q tasks

7.Gradle命令行

  • 查看所有可執行tasks:./gradlew tasks
  • 強制刷新依賴:./gradlew --refresh-dependencies assemble
  • 多任務調用:./gradlew clean jar
  • 查看幫助:./gradlew -?./gradlew -h./gradlew -help

二.Groovy基礎

一句話表明Groovy的地位:Groovy於Gradle,好比Java於Android

1.特性:Groovy是個靈活的動態腳本語言,語法和Java很相似,又兼容Java,且在此基礎上增加了很多動態類型和靈活的特性,如支持閉包和DSL

2.語法

  • 分號不必需
  • 字符串:單引號和雙引號均可定義一個字符串常量,區別在於單引號不能對字符串表達式做運算,而雙引號可以
task printStringVar << {
    def name = "張三”
    println '單引號的變量計算:${name}'
    println "雙引號的變量計算:${name}"
}
運行./gradlew printStringVar輸出結果:
單引號的變量計算:${name}
雙引號的變量計算:張三
  • 集合:以List和Map爲例,介紹如何定義集合和訪問集合元素
//List
task printList<<{
      def numList = [1,2,3,4,5,6];//定義一個List

      println numList[1]//輸出第二個元素
      println numList[-1]//輸出最後一個元素
      println numList[1..3]//輸出第二個到第四個元素
      numList.each{
          println it//輸出每個元素
      }
}
//Map
task printlnMap<<{
    def map1 =['width':1024,'height':768]//定義一個Map
    
    println mapl['width']//輸出width的值
    println mapl.height//輸出height的值
    map1.each{
        println "Key:${it.key},Value:${it.value}"//輸出所有鍵值對
    }
}

  • 方法:方法調用傳參的括號可省略;return不必需,無return時會將最後一行代碼作爲其返回值;允許將代碼塊(閉包)作爲參數傳遞
//以集合的each方法爲例,接受的參數就是一個閉包
numList.each({println it})
//省略傳參的括號,並調整格式,有以下常見形式
numList.each{
    println it
}
  • 不是一定要定義成員變量才能作爲類屬性被訪問,用get/set方法也能當作類屬性
task helloJavaBean<<{
      Person p = new Person()
      p.name = "張三"
      println "名字是: ${p.name}"//輸出類屬性name,爲張三
      println "年齡是: ${p.age}"//輸出類屬性age,爲12
}
class Person{
      private String name
      public int getAge(){//省略return
          12
      }
}
  • 閉包:當閉包有一個參數時,默認爲it,多個參數時需要一一羅列
//單個參數
task helloClosure<<{
    customEach{
        println it
    }
}
def customEach(closure){
    for(int i in 1..10){
        closure(i)
    }
}
//多個參數
task helloClosure<<{
    eachMap{k,v->
        println "${k} is ${v}"
    }
}
def eachMap(closure){
    def map1 = ["name":"張三","age":18]
    map1.each{
        closure(it.key,it.value)
    }
}

三.Gradle構建腳本基礎

1.Settings文件

  • 作用:初始化、設置工程樹
  • 文件名settings.gradle,放在Project下
  • 常用方法:include方法指定能被Gradle識別的Module
//添加:app和:common這兩個module參與構建
include ':app'
project(':app').projectDir = new File('存放目錄')
include':common'
project(':common').projectDir = new File('存放目錄')

2.Build文件

  • Project的build.gradle:整個Project的共有屬性,包括配置版本、插件、依賴庫等信息
  • Module的build.gradle:各個module私有的配置文件

3.Gradle任務

a.含義:指原子性操作

b.關係:一個Gradle可包含多個Project,一個 Project可包含多個Task,即每個Project是由多個Task組成的;Task是Project的屬性,屬性名就是任務名

c.創建

  • 以任務名創建:接受一個name參數
def task myTask = task(myTask)
myTask.doLast{
    println "第一種創建Task方法,原型爲Task task(String name) throws InvalidUserDataException"
}
  • 以任務名+Map創建:Map參數用於對創建的task進行配置,可用配置如下圖
def task myTask = task(myTask,group:BasePlugin.BUILD_GROUP)
myTask.doLast{
    println "第二種創建Task方法,原型爲Task task(String name,Map<String,?> args) throws InvalidUserDataException"
}
  • 以任務名+閉包創建:常見形式
task myTask{
    doLast{
        println "第三種創建Task方法,原型爲Task task(String name,Closure configureClosure)"
    }
}

以上創建方式實際上最終都會調用TaskContainter#create()方法,使用./gradlew myTask命令執行任務

d.訪問

  • 通過任務名訪問:名稱.方法
  • 通過TaskContainter訪問:tasks['名稱'].方法
  • 通過路徑訪問:參數可以爲路徑或名稱
    • get方式:tasks.getByPath('路徑/名稱'),若不存在會拋出UnknownTaskException異常
    • find方式:tasks.findByPath('路徑/名稱'),若不存在返回null
  • 通過名稱訪問:參數只能爲名稱
    • get方式:tasks.getByName('名稱'),若不存在會拋出UnknownTaskException異常
    • find方式:tasks.findByName('名稱'),若不存在返回null

可見任務名稱是唯一的,這是因爲TaskContainer的父類 NamedDomainObjectCopllection是個具有唯一不變名字的域對象的集合

e.依賴:在創建任務時通過dependsOn指定其依賴的任務,可以控制任務的執行順序

task task1<<{
    println 'hello'
}
task task2<<{
    println 'world'
}
//依賴單個任務
task task3(dependsOn:task1){
    doLast{
        println 'one'
    }
}
//依賴多個任務
task task4{
    dependsOn task1,task2
    doLast{
        println 'two'
    }
}

當執行task4時,會發現task1、task2會先執行,再執行task4

注:操作符<< 用在Task定義上相當於doLast

f.排序:除了通過強依賴來控制任務的執行順序,還可以通過 shouldRunAftermustRunAfter 實現

taskB.shouldRunAfter(taskA) //表示taskB應該在taskA執行之後執行,有可能不會按預設執行
taskB.mustRunAfter(taskA) //表示taskB必須在taskA執行之後執行

g.分組& 描述:分組是對任務的分類,便於歸類整理;描述是說明任務的作用;建議兩個一起配置,便於快速瞭解任務的分類和用途

def task myTask = task(myTask)
myTask .group = BasePlugin.BUILD_GROUP
myTask .description = '這是一個構建的引導任務'

h.啓用 & 禁用:enable屬性可以啓動和禁用任務,執行被禁用的任務輸出提示該任務被跳過

def task myTask = task(myTask)
myTask.enable = false //禁用任務

i.執行分析:執行Task的時候實際上是執行其擁有的actions List,它是Task對象實例的成員變量;在創建任務時Gradle會解析其中被TaskAction註解的方法作爲其Task執行的action,並添加到 actions List,其中doFirst和doList會被添加到action List第一位和最後一位

4.自定義屬性

Project、Task和SourceSet都允許用戶添加額外的自定義屬性、並對自定義屬性進行讀取和設置

  • 方式:通過ext屬性,添加多個通過ext代碼塊
  • 優點:相比局部變量有廣泛的作用域,可以跨Project、跨Task訪問,只要能訪問這些屬性所屬的對象即可
//給Project添加自定義屬性
ext.age = 18
ext{
    phone = 13888888888
    address = 'Beijing'
}
//給Task添加自定義屬性
task customProperty {   
    ext.inner = 'innnnnner'                 
                    
    doLast{
        println project.hasProperty('customProperty') //true
        println project.hasProperty('age') //true
        println project.hasProperty('inner')//返回fasle
                
        println "${age}"
        println "${phone}"
        println "${inner}"
    }
}

四.Gradle插件

1.作用

  • 可以添加任務到項目,比如測試、編譯、打包等
  • 可以添加依賴配置到項目,幫助配置項目構建過程中需要的依賴,比如第三方庫等
  • 可以向項目中現有的對象類型添加新的擴展屬性和方法等,幫助配置和優化構建
  • 可以對項目進行一些約定,比如約定源代碼存放位置等

Gradle本身內置許多常用的插件,如若需要還可以擴展現有插件或者自定義插件,如Android Gradle插件就是基於內置的Java插件實現的

2.擴展現有插件

a.插件種類

  • 二進制插件:實現org.gradle.api.Plugin接口的插件,可以有plugin id
  • 腳本插件:嚴格上只是一個腳本,可以來自本地或網路

b.應用插件:通過Project#apply()方法,有三種用法

  • Map參數:void apply (Map<String, ?> options)
    • 二進制插件:
      • id:apply plugin:'java'
      • 類型:apply plugin:org.gradle.api.plugins.JavaPlugin
      • 簡寫:apply plugin:JavaPlugin
    • 腳本插件:apply from:'version.gradle'
    • 第三方發佈插件:apply plugin:'com.android.application'

注意:應用第三方發佈的作爲jar的二進制插件時,必須先在buildscript{}配置其classpath才能使用,否則會提示找不到該插件

//buildscript:爲項目進行前提準備和初始化相關配置依賴
buildscript {
    repositories {
        jcenter ()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0"
    }
}
apply plugin:'com.android.application
  • 閉包:void apply (Closure closure)
apply {
    plugin:'java'
}
  • Action:void apply (Action<? super ObjectConfigurationActicn> action)

3.自定義插件:實現Plugin接口、重寫apply()方法


五.Java Gradle插件

1.項目結構

使用Java插件要先應用進來:

apply plugin:'java'

此時會添加許多默認設置和約定,比如有以下默認項目結構:

|-example
|  |-build.gradle
|  |-src
|    |-main
|       |-java  源代碼存放目錄
|       |-resources  打包文件存放目錄
|    |-test
|       |-java 單元測試用例存放目錄
|       |-resources 單元測試中使用的文件

2.源集(SourceSet)

  • 作用:用於描述和管理源代碼(java)及其資源(resources),如訪問源代碼目錄、設置源集屬性、更改Java原代碼目錄等
  • 方式:通過sourceSets屬性(是一個SourceSetsContainer)和sourceSets{}閉包
  • 常用屬性

比如,在上述Java插件默認項目結構中的main和test就是內置的兩個源集,現在更改main源集的Java源文件的存放目錄到src/java下:

apply plugin:'java'
sourceSets{
    main{
        java{
            srcDir 'src/java'
        }
    }
}
  • 定義新源集:通過sourceSets{}閉包添加
apply plugin:'java'
sourceSets{
    vip{
    }
}

此時會新建兩個目錄:src/vip/java和src/vip/resources

補充:除了SourceSet,Java插件裏常用的其他屬性:

3.配置第三方依賴

a.依賴方式

  • 外部依賴:依賴外部倉庫,如Maven、Ivy等
  • 項目依賴:依賴項目,依賴後可以使用該項目的Java類
  • 文件依賴:如依賴Jar包,出於安全考慮不發佈到Maven而是放在項目的libs文件夾下

b.具體方法

  • 對於外部依賴,需要先在repositories{}閉包裏聲明依賴庫的位置
  • dependencies{}閉包添加依賴
    • 外部依賴:說明依賴庫的group:name:version
    • 項目依賴:project('項目名稱')
    • 文件依賴:files('文件名稱'),多個文件逗號分開,或者fileTree(dir:'文件名稱',include:'*.擴展名稱')依賴指定文件夾下指定擴展名文件
  • 幾種依賴類型

舉例:

apply plugin:'java'
repositories {
    //外部依賴 依賴Maven中心庫
    maveCentral() 
}
dependencies {
    //外部依賴 完整寫法
    compile group:'com.squareup.okhttp3',name:'okhttp', version:'3.0.1'   
    //外部依賴 簡單寫法
    compile 'com.squareup.okhttp3:okhttp:3.0.1'    
    //外部依賴 指定main源集依賴
    mainCompile 'com.squareup.okhttp3:okhttp:3.0.1'   
    //項目依賴
    compile project(':example')    
    //文件依賴 依賴libs下兩個Jar包
    compile files('libs/example01.jar', 'libs/example02.jar')   
    //文件依賴 指定依賴libs下所有Jar包
    compile fileTree(dir: 'libs',include: '*.jar')
}

4.內置任務

常用幾種任務:

  • build任務:構建項目
  • clean任務:刪除build目錄及構建生成的文件
  • assemble任務:不執行單元測試,只編譯和打包
  • check任務:只執行單元測試
  • javadoc任務:生成Java格式的doc api文檔

還有些通用任務、對源集適用的任務:

5.多項目構建

  • 含義:多個Gradle項目一起構建
  • 方式:通過settings.gradle配置管理多項目;在每個項目都有一個build.gradle,採用項目依賴就能實現多項目協作
//settings.gradle
include ':app'
project(':app').projectDir = new File('存放目錄')
include ':base'
project(':base').projectDir = new File('存放目錄')

//app/build.gradle
apply plugin:'java'
dependencies {
    compile project(':base')    
}

6.發佈構件

  • 構件:Gradle構建的產物,如Jar包、Zip包等
  • 意義:發佈構建給其他工程使用,可以發佈到本地目錄、Maven、Ivy等
  • 方式:明確構件類型,並通過artifacts{}閉包配置需要發佈的構建,在uploadArchives{}上傳發布構件
//以發佈jar構件爲例
apply plugin:'java '
task publishJar(type:Jar)
artifacts{
    archives publishJar
}
uploadArchives{
    repositories{
        //發佈到本地目錄
        flatDir{
            name 'libs'
            dirs "$projectDir/libs"
        }
        //發佈到本地Maven庫
        mavenLocal()
    }
}

六.Android Gradle插件

1.概述

Android Gradle插件繼承於Java插件,具有Java插件的所有特性,也有自己的特性,看下官方介紹:

  • 可以很容易地重用代碼和資源
  • 可以很容易地創建應用的衍生版本
  • 可以很容易地配置、擴展以及自定義構建過程
  • 和IDE無縫整合

2.插件分類

  • App應用工程:生成可運行apk應用;id: com.android.application
  • Library庫工程:生成aar包給其他的App工程公用;id: com.android.library
  • Test測試工程:對App應用工程或Library庫工程進行單元測試;id: com.android.test

3.項目結構

|-example
|  |-build.gradle
|  |-example.iml
|  |-libs
|  |-proguard-rules.pro  混淆配置文件
|  |-src
|    |-androidTest
|       |-java  Android單元測試代碼
|    |-main
|       |-java  App主代碼
|       |-res   資源文件
|       |-AndroidManifest.xml  配置文件
|    |-test
|       |-java 普通單元測試代碼

4.內置任務

  • Java插件內置任務:如build、assemble、check等
  • Android特有的常用任務:
    • connectedCheck任務:在所有連接的設備或者模擬器上運行check檢查
    • deviceCheck任務:通過API連接遠程設備運行checks
    • lint任務:在所有ProductFlavor上運行lint檢查
    • installuninstall任務:在已連接的設備上安裝或者卸載App
    • signingReport任務:打印App簽名
    • androidDependencies任務:打印Android 依賴

5.應用實例

//應用插件,Android Gradle屬於Android發佈的第三方插件
buildscript{
    repositories{
        jcenter()
    }
    dependencies{
        classpath 'com.android.tcols.build:gradle:1.5.0'
    }
}
apply plugin:'com.android.application'
//自定義配置入口,後續詳解
android{
    compileSdkVersion 23 //編譯Android工程的SDK版本
    buildToolsVersion "23.0.1" //構建Android工程所用的構建工具版本

    defaultConfig{
        applicationId "org.minmin.app.example"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes{
        release{
            minifyEnabled false
            proguardFiles getDefaultPraguardFile('proguard-andrcid.txt'), 'proguard-rules.pro'
        }
    }
}
//配置第三方依賴
dependencies{
    compile fileTree(dir:'libs', include:['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcorpat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

a.defaultConfig

  • 作用:用於定義所有的默認配置,是一個ProductFlavor,若ProductFlavor沒有被特殊定義,默認使用defaultConfig塊指定的配置
  • 常用配置
屬性名 含義
applicationId 指定App包名
minSdkVersion 指定App最低支持的Android SDK
targetSdkVersion 指定基於的Android SDK
versionCode 配置Android App的內部版本號
versionName 配置Android App的版本名稱
testApplicationId 配置測試App的包名,默認爲applicationId + “.test”
testInstrumentationRunner 配置單元測試使用的Runner,默認爲android.test.InstrumentationTestRunner
proguardFile 配置App ProGuard混淆所使用的ProGuard配置文件
proguardFiles 同時配置多個ProGuard配置文件
signingConfig 配置默認的簽名信息,也是一個ProductFlavor,可直接配置

b.buildTypes

  • 作用:是構建類型,在Android Gradle中內置了debug和release兩個構建類型,差別在於能否在設備上調試和簽名不同
  • 每一個BuildType都會生成一個SourceSet以及相應的assemble<BuildTypeName>任務
  • 常用配置
屬性名 含義
applicationIdSuffix 配置基於默認applicationId的後綴
debuggable 是否生成一個可供調試的Apk
jniDebuggable 是否生成一個可供調試JNI代碼的Apk
minifyEnabled 是否啓用Proguard混淆
multiDexEnabled 是否啓用自動拆分多個Dex的功能
zipAlignEnabled 是否開啓開啓zipalign優化,提高apk運行效率
shrinkResources 是否自動清理未使用的資源,默認爲false
proguardFile 配置Proguard混淆使用的配置文件
proguardFiles 同時配置多個ProGuard配置文件
signingConfig 配置默認的簽名信息,也是一個ProductFlavor,可直接配置

c.signingConfigs

  • 作用:配置簽名設置,標記App唯一性、保護App
  • 可以對不同構建類型採用不同簽名方式:debug模式用於開發調試,可以直接使用Android SDK提供的默認debug簽名證書;release模式用於發佈,需要手動配置
  • 常用配置
屬性名 含義
storeFile 簽名證書文件
storePassword 簽名證書文件的密碼
storeType 簽名證書的類型
keyAlias 簽名證書中密鑰別名
keyPassword 簽名證書中該密鑰的密碼
android {
    signingConfigs {
        release{
            storeFile file('myFile.keystore')
            storePassword 'psw'
            keyAlias 'myKey'
            keyPassword 'psw'
        }
    }
}

d.productFlavors

  • 作用:添加不同的渠道、並對其做不同的處理
  • 常用配置
屬性名 含義
applicationId 設置該渠道的包名
consumerProguardFiles 對aar包進行混淆
manifestPlaceholders
multiDexEnabled 啓用多個dex的配置,可突破65535方法問題
proguardFiles 混淆使用的文件配置
signingConfig 簽名配置
testApplicationId 適配測試包的包名
testFunctionalTest 是否是功能測試
testHandleProfiling 是否啓用分析功能
testInstrumentationRunner 配置運行測試使用的Instrumentation Runner的類名
testInstrumentationRunnerArguments 配置Instrumentation Runner使用的參數
useJack 標記是否啓用Jack和Jill這個全新的、高性能的編譯器
dimension 維度,通過flavorDimensions方法聲明,聲明前後代表優先級
//定義baidu和google兩個渠道,並聲明兩個維度,優先級爲abi>version>defaultConfig
android{
    flavorDimensions "abi", "version"
    productFlavors{
        google{
            dimension "abi"
        }
       baidu{ 
           dimension "version"
       } 
}

e.buildConfigFiled

  • 作用:在buildTypes、ProductFlavor自定義字段等配置
  • 方法buildConfigField(String type,String name,String value)
    • type:字段類型
    • name:字段常量名
    • value:字段常量值
android{
   buildTypes{
        debug{
            buildConfigField "boolean", "LOG_DEBUG", "true"
            buildConfigField "String", "URL", ' "http://www.ecjtu.jx.cn/" '
        }
    }
}

6.多項目構建

和Java Grdle多項目構建一樣的,通過settings.gradle配置管理多項目;在每個項目都有一個build.gradle,採用項目依賴就能實現多項目協作。

項目直接依賴一般適用於關聯較緊密、不可複用的項目,如果想讓項目被其他項目所複用,比如公共組件庫、工具庫等,可以單獨發佈出去。

7.多渠道構建

a.基本原理

  • 構建變體(Build Variant)=構建類型(Build Type)+構建渠道(Product Flavor)

Build Type有release、debug兩種構建類型
Product Flavor有baidu、google兩種構建渠道
Build Variant有baiduRelease、baiduDebug、googleRelease、googleDebug四種構件產出

  • 構建渠道(Product Flavor)還可以通過dimension進一步細化分組

  • assemble開頭的負責生成構件產物(Apk)

assembleBaidu:運行後會生成baidu渠道的release和debug包
assembleRelease:運行後會生成所有渠道的release包
assembleBaiduRelease:運行後只會生成baidu的release包

b.構建方式:通過佔位符manifestPlaceholders實現:

//AndroidManifest
<meta-data 
    android: value="Channel ID" 
    android:name="UMENG_ CHANNEL"/>
//build.gradle
android{
    productFlavors{
        google{
            manifestPlaceholders.put("UMENG_ CHANNEL", "google")
        }
       baidu{
            manifestPlaceholders.put("UMENG_ CHANEL", "baidu")
       }
}
//改進:通過productFlavors批量修改
android{
    productFlavors{
        google{
        }
       baidu{
       }
       ProductFlavors.all{ flavor->
           manifestPlaceholders.put("UMENG_ CHANEL", name) 
       }        
}

8.高級應用

a. 使用共享庫

  • android sdk庫:系統會自動鏈接
  • 共享庫:獨立庫,不會被系統自動鏈接,使用時需要在AndroidManifest通過<uses-library>指定
//聲明需要使用maps共享庫,true表示如果手機系統不滿足將不能安裝該應用
<uses-library
    android:name="com.google.android.maps"
    android:required="true" 
/>
  • add-ons庫:存於add-ons目錄下,大部分由第三方廠商或公司開發,會被自動解析添加到classpath
  • optional可選庫:位於platforms/android-xx/optional目錄下,通常爲了兼容舊版本的API,使用時需要手動添加到classpath

b. 批量修改生成的apk文件名

  • 類型:
    • applicationVariants :僅僅適用於Android應用Gradle插件
    • libraryVariants :僅僅適用於Android庫Gradle插件
    • testVariants :以上兩種Gradle插件都使用
  • 示例:

applicationVariants是一個DomainObjectCollection集合,通過all方法遍歷每一個ApplicationVariant,這裏有googleRelease和googleDebug兩個變體;然後判斷名字是否以.apk結尾,如果是就修改其文件名。示例中共有。

c.動態生成版本信息

  • 原始方式:由defaultConfig中的versionName指定
  • 分模塊方式:把版本號等配置抽出放在單獨的文件裏,並用ext{}括起來,通過apply from將其引入到build.gradle,版本信息就被當作擴展屬性直接使用了
  • 從git的tag中獲取
  • 從屬性文件中動態獲取和遞增

d.隱藏簽名文件信息

  • 必要性:爲保證簽名信息安全,最好直接放在項目中,而是放在服務器上
  • 一種思路
    • 服務器:配置好環境變量,打包時直接使用
    • 本地:直接使用android提供的debug簽名
    • 在signingConfigs加入以下判斷
signingConfigs {
    if (System.env.KEYSTORE_PATH != null) {
        //打包服務器走這個邏輯
        storeFile file(System.env.KEYSTORE_PATH)
        keyAlias System.env.ALIAS
        keyPassword System.env.KEYPASS
        storePassword System.env.STOREPASS
    } else {
        //當不能從環境變量取到簽名信息時,使用本地debug簽名
        storeFile file('debug.keystore')
        storePassword 'android'
        keyAlias 'androiddebugkey'
        keyPassword 'android'
    }
}

e.動態添加自定義的資源

  • 針對res/values中的資源,除了使用xml定義,還可以通過Android Gradle定義
  • 方法:resValue(String type, String name, String value)
    • type:資源類型,如有string、id、bool
    • name:資源名稱,以便在工程中引用
    • value:資源值
productFlavors{
   google{
       resValue 'string', 'channel_tips', 'google渠道歡迎你'
   }
}

以google爲例,在debug模式下,資源文件保存目錄:build/generated/res/resValues/google/debug/values/generated.xml

f.Java編譯選項

通過compileOptions{}閉包進行編譯配置,可配置項:

  • encoding:配置源文件的編碼
  • sourceCompatibility:配置Java源代碼的編譯級別
  • targetCompatibility:配置生成Java字節碼的版本
 android{
      compileOptions{
         encoding = 'utf-8'
         sourceCompatibility = JavaVersion.VERSI0N_ 1_ 6
         targetCompatibility = JavaVersion.VERSION_ 1_ 6
     }
}

g. adb選項配置

通過adbOptions{}閉包進行adb配置,可配置項:

  • timeOutInMs:設置執行adb命令的超時時間,單位毫秒
  • installOptions:設置adb install安裝設置項
    • -l:鎖定該應用程序
    • -r:替換已存在的應用程序,即強制安裝
    • -t:允許測試包
    • -s:把應用程序安裝到SD卡上
    • -d:允許進行降級安裝,即安裝版本比手機自帶的低
    • -g:爲該應用授予所有運行時的權限
android{
    adbOptions{
        timeOutInMs = 5*1000
        installOptions '-r', '-s'
    }
}

h.DEX選項配置

通過dexOptions {}閉包進行dex配置,可配置項:

  • incremental:配置是否啓用dx的增量模式,默認值爲false
  • javaMaxHeapSize:配置執行dx命令時爲其分配的最大堆內存
  • jumboMode:配置是否開啓jumbo模式
  • preDexLibraries:配置是否預dex Libraries庫工程,默認值爲true,開啓後會提高增量構建的速度
  • threadCount:配置Android Gradle運行dx命令時使用的線程數量

PS:這周沒有周記,期待明天開始的團建活動~
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章