乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Android Gradle 使用教程

       mediatv 2019-11-19
      gradle

      1.介紹

      如果你正在查閱build.gradle文件的所有可選項(xiàng),請(qǐng)點(diǎn)擊這里進(jìn)行查閱:DSL參考

      1.1新構(gòu)建系統(tǒng)的特性

      gradle構(gòu)建系統(tǒng)具有如下的特點(diǎn):

      • 易于代碼和資源復(fù)用
      • 易于創(chuàng)建應(yīng)用的版本,例如發(fā)布多apk以及應(yīng)用的不同渠道版本
      • 構(gòu)建過(guò)程易于配置,擴(kuò)展和優(yōu)化
      • 良好的IDE整合

      1.2為什么使用Gradle?

      Gradle既是一個(gè)先進(jìn)的構(gòu)建系統(tǒng),也是一個(gè)允許通過(guò)插件創(chuàng)建自定義構(gòu)建邏輯的構(gòu)建工具集。以下是一些我們?yōu)槭裁催x擇Gradle的原因:

      • 用于描述和操作構(gòu)建邏輯的,基于Groovy的特定領(lǐng)域語(yǔ)言(DSL)
      • 基于Groovy的構(gòu)建文件,允許混合通過(guò)使用DSL的聲明式元素以及使用代碼去操作DSL元素來(lái)提供自定義邏輯。
      • 通過(guò)Maven或者Ivy的內(nèi)置依賴管理
      • 非常靈活。
      • 插件能夠?qū)С鲎约旱腄SL以及自己的API,用于使用構(gòu)建文件
      • 支持IDE整合的良好工具API

      1.3要求

      • Gradle 2.2
      • SDK版本19.0.0及以上,一些特性可能會(huì)需要更新的版本

      2.基礎(chǔ)項(xiàng)目搭建

      一個(gè)Gradle項(xiàng)目在一個(gè)文件中描述了該項(xiàng)目的構(gòu)建情況,該文件被稱為build.gradle,位于項(xiàng)目的根目錄。(點(diǎn)擊這里查看構(gòu)建系統(tǒng)概述)

      2.1簡(jiǎn)單的構(gòu)建文件

      大多數(shù)簡(jiǎn)單的Android項(xiàng)目擁有如下的build.gradle文件:

      buildscript {
          repositories { 
              jcenter()
          }
          dependencies {
              classpath 'com.android.tools.build:gradle:1.3.1'
          }
      }
      apply plugin: 'com.android.application'
      android {
          compileSdkVersion 23
          buildToolsVersion "23.1.0"
      }
      

      在Android的構(gòu)建文件中,有以下三個(gè)主要區(qū)域:
      buildscript{…}用于配置用于構(gòu)建的代碼。在上面的例子中,聲明使用jCenter庫(kù),并且有一個(gè)依賴于Maven類路徑的Maven Artifact。該Artifact是包含包含Android構(gòu)建插件的1.3.1版本Gradle。

      上例中的Artifact僅僅影響到構(gòu)建代碼的運(yùn)行,并不作用于代碼項(xiàng)目。至于項(xiàng)目本身需要聲明自己的庫(kù)和依賴關(guān)系,該部分將會(huì)在下文介紹。

      之后,該構(gòu)建文件應(yīng)用了com.android.application插件。該插件用于構(gòu)建Android應(yīng)用。
      最后android{…}中配置了所有用于Android應(yīng)用構(gòu)建的參數(shù)。這里是Android特定領(lǐng)域語(yǔ)言(DSL)的入口點(diǎn)。默認(rèn)情況下,僅僅編譯目標(biāo)(compilation target)和構(gòu)建工具版本(version of the build-tool)是必備的。也就是上例中的compileSdkVersion屬性和buildtoolsVersion屬性。該編譯目標(biāo)和舊版本的project.properties文件中的target屬性是相同的。新版本中既可以指定一個(gè)整型(即API level),也可以使用表示相同值的字符串對(duì)compileSdkVersion進(jìn)行指定。

      重點(diǎn):你應(yīng)當(dāng)使用com.android.application插件,使用java插件會(huì)導(dǎo)致錯(cuò)誤。
      注意1:另外,你也需要一個(gè)local.properties文件,設(shè)置sdk.dir去配置本地的SDK路徑位置。
      注意2:另外,你也可以設(shè)置名為ANDROID_HOME的環(huán)境變量。 這兩者并沒(méi)有什么區(qū)別,你可以選擇任意一種。例如:sdk.dir=/path/to/Android/Sdk

      2.2項(xiàng)目結(jié)構(gòu)

      上面例子的基本構(gòu)建文件預(yù)期了一個(gè)默認(rèn)的文件夾結(jié)構(gòu)。Gradle遵循“約定優(yōu)于配置”的概念,盡可能提供良好的默認(rèn)項(xiàng)值。基本項(xiàng)目由兩個(gè)被稱為代碼集(source sets)的部分構(gòu)成,一個(gè)是主要的源代碼,另一個(gè)是測(cè)試代碼。它們各自位于:

      • src/main
      • src/androidTest

      在這些目錄里,每一個(gè)資源組件都有各自的子目錄。對(duì)于Java和Android插件,java源代碼和java資源的路徑位置為:

      • java/
      • resources/

      對(duì)于Android插件而言,有如下特定的文件和目錄:

      • AndroidManifest.xml
      • res/
      • assets
      • aidl/
      • rs/
      • jni/
      • jniLibs/

      這意味著主資源集中的所有*.java文件位于src/main.java中,主清單文件(main manifest)位于src/main/AndroidManifest.xml。

      注意:
      src/androidTest/AndroidManifest.xml由于會(huì)自動(dòng)創(chuàng)建,因此并不是必須手動(dòng)編寫的。

      2.2.1配置結(jié)構(gòu)

      當(dāng)默認(rèn)的項(xiàng)目結(jié)構(gòu)并不完善時(shí),可能需要進(jìn)行配置。本部分只介紹Android項(xiàng)目結(jié)構(gòu)的配置,關(guān)于純java項(xiàng)目的項(xiàng)目結(jié)構(gòu)配置,請(qǐng)參閱:gradle documentation。
      Android插件使用和純java項(xiàng)目相同的語(yǔ)法,但是由于其使用自己的資源集,項(xiàng)目的配置由android{...}代碼塊完成。例如,舊的項(xiàng)目結(jié)構(gòu)(Eclipse)中對(duì)主代碼和測(cè)試代碼進(jìn)行映射:

      android {
          sourceSets {
              main {
                  manifest.srcFile 'AndroidManifest.xml'
                  java.srcDirs = ['src']
                  resources.srcDirs = ['src']
                  aidl.srcDirs = ['src']
                  renderscript.srcDirs = ['src']
                  res.srcDirs = ['res']
                  assets.srcDirs = ['assets']
              }
      
       androidTest.setRoot('tests')
            }
      }
      

      注1: 因?yàn)榕f的結(jié)構(gòu)中在同一個(gè)文件夾中放入所有的資源文件,我們需要對(duì)這些資源集重新進(jìn)行映射,將java代碼,資源文件等等放入src文件夾。
      注2: setRoot()移動(dòng)整個(gè)資源集和其子文件夾到一個(gè)新的文件夾中,上例將src/androidTest/*移動(dòng)到tests/* 中,當(dāng)然此處的語(yǔ)句androidTest.setRoot('tests')只是Android的特性,并不適用于Java的資源集。

      2.3構(gòu)建的任務(wù)

      2.3.1通用任務(wù)

      在構(gòu)建文件中應(yīng)用插件會(huì)自動(dòng)創(chuàng)建一系列構(gòu)建任務(wù)的集合。Java插件和Android插件都是如此。關(guān)于任務(wù)的約定如下:

      • assemble 該任務(wù)用于組合項(xiàng)目的輸出
        • check 該任務(wù)用于運(yùn)行所有的的檢測(cè)
        • build 該任務(wù)執(zhí)行assemble和check任務(wù)
        • clean該任務(wù)清除項(xiàng)目的輸出

      任務(wù)assemble,check以及build并不真正做任何事。這些插件中的“祖先”任務(wù)用于添加在任務(wù)中真正執(zhí)行的任務(wù)。
      這樣,不論當(dāng)前的任務(wù)類型是什么以及何種插件被應(yīng)用,都將會(huì)允許你使用執(zhí)行相同的任務(wù)。例如,findbugs插件將會(huì)創(chuàng)建一個(gè)一個(gè)新的任務(wù),并通過(guò)check任務(wù)進(jìn)行依賴,無(wú)論什么時(shí)候執(zhí)行調(diào)用該任務(wù),都可以直接使用check任務(wù)。
      在命令行中,你可以通過(guò)下面的命令得到高級(jí)別任務(wù):
      gradle tasks
      查看所有依賴任務(wù)列表可以使用下面的命令:
      gradle tasks —all

      注意:gradle自動(dòng)顯示任務(wù)已經(jīng)聲明任務(wù)的輸入和輸出情況。

      當(dāng)你在沒(méi)有變更項(xiàng)目?jī)?nèi)容的情況下再次運(yùn)行構(gòu)建任務(wù)時(shí),Gradle將會(huì)報(bào)告所有的任務(wù)已經(jīng)UP-TO-DATE,意味著沒(méi)有需要運(yùn)行的任務(wù)。這樣會(huì)使得任務(wù)彼此正確的依賴,而不需要沒(méi)必要的構(gòu)建操作。

      2.3.2Java項(xiàng)目任務(wù)

      以下是由Java插件所創(chuàng)建的,依賴于祖先任務(wù)的最重要的兩個(gè)任務(wù):

      • assemble jar:創(chuàng)建輸出的任務(wù)
      • check test:運(yùn)行測(cè)試的任務(wù)

      jar任務(wù)本身直接或間接依賴于其他任務(wù):例如classes任務(wù)將會(huì)編譯Java代碼。測(cè)試代碼被任務(wù)testClasses所編譯,但是就像classes任務(wù)一樣,幾乎很少有人會(huì)去調(diào)用,因?yàn)閳?zhí)行test任務(wù)即可。
      總的來(lái)說(shuō),你可能應(yīng)當(dāng)僅僅調(diào)用assemble任務(wù)或者check任務(wù)并忽略其他的任務(wù)。你可以點(diǎn)擊這里查看Java插件所有的任務(wù)集合及其描述信息:Java插件的任務(wù)集合

      2.3.3Android的任務(wù)

      Android插件使用相同的概念來(lái)保持和其他插件之間的兼容性,并且,Android插件還添加了額外的祖先任務(wù):

      • assemble
      • check
      • connectedCheck 運(yùn)行check任務(wù)需要一個(gè)連接的設(shè)備或者模擬器,在所有的連接設(shè)備中,該任務(wù)將并行執(zhí)行。
      • deviceCheck 使用API去連接遠(yuǎn)程設(shè)備,用于CI服務(wù)器(持續(xù)集成服務(wù)器)。
      • build
      • clean

      新的祖先任務(wù)是必備的,這是為了能夠在不需要連接設(shè)備的情況下進(jìn)行規(guī)則檢查。請(qǐng)注意,build任務(wù)并不依賴deviceCheck任務(wù)或者connectedCheck任務(wù)。
      一個(gè)Android的項(xiàng)目有至少兩個(gè)輸出文件:一個(gè)debug apk文件以及一個(gè)release apk文件。它們中的每一個(gè)都有其自己的祖先任務(wù)來(lái)優(yōu)化構(gòu)建:

      • assemble
        • assembleDebug
        • assembleRelease

      assembleDebug和assembleRelease兩者都依賴于其他的多步任務(wù)執(zhí)行來(lái)構(gòu)建app文件。assemble任務(wù)依賴于assembleDebug和assembleRelease,可調(diào)用assemble任務(wù)構(gòu)建上述兩種apk。

      提示: gradle支持駱駝命名法縮寫的形式在命令行中為任務(wù)命名。例如:
      gradle aR
      和下面的命令相同:
      gradle assembleRelease
      除非有其他任務(wù)和’aR’重復(fù)。

      check任務(wù)有自己的依賴項(xiàng):

      • check
        • lint
      • connectedCheck
        • connectedAndroidTest
      • deviceCheck
        • 這取決于當(dāng)任務(wù)創(chuàng)建時(shí),其他插件什么時(shí)候?qū)崿F(xiàn)測(cè)試拓展點(diǎn)。

      最后,插件創(chuàng)建了安裝了卸載所有構(gòu)建類型的任務(wù)(包括debug,release和test),只要能夠被安裝(需要簽名)。例如:

      • installDebug
      • installRelease
      • uninstallAll
        • uninstallDebug
        • uninstallRelease
        • uninstallDebugAndroidTest

      2.4構(gòu)建自定義基礎(chǔ)

      Android插件提供了一個(gè)寬泛的領(lǐng)域定制語(yǔ)言(DSL)在構(gòu)建系統(tǒng)中對(duì)大多數(shù)內(nèi)容進(jìn)行自定義。

      2.4.1Manifest條目

      通過(guò)DSL,能夠配置最重要的manifest條目,例如:

      • minSdkVersion
      • targetSdkVersion
      • versionCode
      • versionName
      • applicationId 關(guān)于包名,詳情請(qǐng)點(diǎn)擊:應(yīng)用ID VS 包名
      • testApplicationId (用于測(cè)試apk)
      • testInstrumentationRunner

      例如:

      android {
          compileSdkVersion 23
          buildToolsVersion "23.0.1"
      
      
          defaultConfig { 
              versionCode 12
              versionName "2.0"
              minSdkVersion 16
              targetSdkVersion 23
          }
      }
      

      關(guān)于完整的構(gòu)建屬性清單以及其默認(rèn)值,請(qǐng)查看Android插件特定領(lǐng)域語(yǔ)言參考。
      把這些清單屬性放入構(gòu)建文件中的好處是,這些值可以動(dòng)態(tài)獲取。例如,別人可以從文件中閱讀版本名稱或者使用自定義邏輯:

      def computeVersionName() {
          //...
      }
      android {
          compileSdkVersion 23
          buildToolsVersion "23.0.1"
          defaultConfig {
              versionCode 12 
              versionName computeVersionName()
              minSdkVersion 16
              targetSdkVersion 23
          }
      }
      

      注意:不要使用當(dāng)前域中可能和getters沖突的文件名。例如defaultConfig{...}調(diào)用getVersionName()會(huì)自動(dòng)使用defaultConfig.getVersion()而不是自定義的方法。

      2.4.2構(gòu)建類型

      默認(rèn)情況下,Android插件自動(dòng)建立了debug版和release版應(yīng)用。二者最大的不同是在安全設(shè)備(非開發(fā)設(shè)備)上的調(diào)試能力,以及APK文件被簽名的詳情信息。debug版本是由已知用戶名/密碼(防止在構(gòu)建過(guò)程中的提示)所自動(dòng)創(chuàng)建的key/證書所簽名。release版本在構(gòu)建過(guò)程中并不被簽名,這將會(huì)在后面發(fā)生。
      這項(xiàng)配置通過(guò)一個(gè)叫做BuildType的對(duì)象完成。默認(rèn)情況下,有兩個(gè)實(shí)例被創(chuàng)建,分別是debug版和release版。Android插件運(yùn)行自定義這兩個(gè)實(shí)例,就像其他構(gòu)建類型一樣。這是由buildTypes特定領(lǐng)域語(yǔ)言容器所完成的:

      android {
          buildTypes {
              debug {
                  applicationIdSuffix ".debug"
              }
      
      
              jnidebug {
                  initWith(buildTypes.debug)
                  applicationIdSuffix ".jnidebug"
                  jniDebuggable true
              }
          }
      }
      

      上述片斷實(shí)現(xiàn)了如下內(nèi)容:

      • 配置默認(rèn)的debug構(gòu)建類型
        • 設(shè)置包為”應(yīng)用ID.debug”,使得應(yīng)用的debug版和release版都能在同一個(gè)設(shè)備上安裝。
      • 創(chuàng)建了一個(gè)新的叫作jnidebug的構(gòu)建類型,并對(duì)其使用debug構(gòu)建類型進(jìn)行復(fù)制。
      • 繼續(xù)配置jnidebug,開啟JNI組件調(diào)試功能,并添加一個(gè)不同的包名后綴。

      創(chuàng)建一個(gè)新的構(gòu)建類型就和使用buildTypes容器下的一個(gè)新元素一樣簡(jiǎn)單,要么調(diào)用initWith()要么將其完全配置結(jié)束。關(guān)于構(gòu)建類型的完整屬性清單,請(qǐng)查閱:Android構(gòu)建類型參考
      另外,關(guān)于修改構(gòu)建屬性,構(gòu)建類型可以用于添加指定的代碼和資源文件。對(duì)每一種構(gòu)建類型,新的相匹配資源集被創(chuàng)建,其默認(rèn)位置為”src/構(gòu)建類型名稱”,例如src/debug/java目錄能夠用于添加僅僅在debug APK文件中所編譯的代碼或資源文件。這意味著構(gòu)建類型的命名不能和main以及androidTest重復(fù)(,并且必須獨(dú)一無(wú)二(這是插件所限制的)。
      就像其他任何的資源集一樣,構(gòu)建類型資源的位置能夠重新指定:

      android {
          sourceSets.jnidebug.setRoot('foo/jnidebug')
      }
      

      此外,對(duì)于每一種構(gòu)建類型,一個(gè)新的assemble構(gòu)建類型名稱任務(wù)被創(chuàng)建,例如assembleDebug。assembleDebug任務(wù)和assembleRelease任務(wù)在上文中已經(jīng)被提及,這也就是他們?yōu)槭裁磿?huì)存在的原因。當(dāng)debug構(gòu)建類型和release構(gòu)建類型預(yù)創(chuàng)建時(shí),這些任務(wù)(assembleDebugassembleRelease)也會(huì)被自動(dòng)創(chuàng)建。根據(jù)這個(gè)規(guī)則,上述的build.gradle片段也將會(huì)生成一個(gè)叫做assembleJnidebug的任務(wù),該任務(wù)的依賴關(guān)系也和assembleDebug以及assembleRelease一樣。

      提示:請(qǐng)記得你能夠輸入aJ來(lái)運(yùn)行assembleJnidebug任務(wù)。

      可能的使用情況:

      • 一些權(quán)限只在debug模式下開啟,在release模式下禁用
      • 調(diào)試的自定義實(shí)現(xiàn)
      • debug模式下的使用資源不同(例如當(dāng)一個(gè)資源值與資源證書相掛鉤時(shí))
        不同構(gòu)建類型的代碼/資源被用于以下情況:
      • Manifest清單被合并到app清單文件中
      • 作為其他資源文件夾的代碼
      • 資源文件被主資源文件覆蓋并替換現(xiàn)有的值

      2.4.3簽名配置

      對(duì)一個(gè)應(yīng)用的簽名需要以下內(nèi)容(關(guān)于APK文件簽名的詳細(xì)信息,請(qǐng)查閱簽名你的應(yīng)用):

      • keystore
      • keystore密碼
      • keystore別名
      • key密碼
      • 商店類型

      位置,key名稱以及密碼和商店類型共同構(gòu)成簽名配置。默認(rèn)情況下,debug配置使用debug keystore,其帶有已知的密碼和默認(rèn)的key和key的密碼。debug的keystore位于$HOME/.android/debug.keystore,如果不存在會(huì)被創(chuàng)建。debug構(gòu)建類型被自動(dòng)設(shè)成使用debug簽名配置。
      創(chuàng)建其他配置信息或自定義默認(rèn)的內(nèi)置配置信息是可行的。這是通過(guò)signingConfigs特定領(lǐng)域語(yǔ)言容器完成的:

      android {
          signingConfigs {
              debug {
                          storeFile file("debug.keystore")
              }
      
              myConfig {
                  storeFile file("other.keystore")
                  storePassword "android"            keyAlias "androiddebugkey"
                  keyPassword "android"
              }
          }
      
      
          buildTypes {
              foo {
                  signingConfig signingConfigs.myConfig
              }
          }
      }
      

      上述片段改變了debug版本keystore文件的位置為項(xiàng)目的根目錄。這將會(huì)自動(dòng)影響到任何構(gòu)建類型,任何構(gòu)建類型都能夠使用它。在上例中即為debug構(gòu)建類型。這也將會(huì)創(chuàng)建一個(gè)新的簽名配置,新的構(gòu)建類型(foot)便可以使用這個(gè)新的簽名配置。

      注意1:只有debug keystore文件自動(dòng)創(chuàng)建并位于默認(rèn)位置。改變debug keystore文件位置并不會(huì)按需創(chuàng)建。只有使用不同命名創(chuàng)建簽名配置并使用默認(rèn)的debug keystore位置的情況下才會(huì)自動(dòng)創(chuàng)建。從另一方面來(lái)說(shuō),這是和keystore文件的位置掛鉤的,而不是和配置信息的命名相對(duì)應(yīng)的。
      注意2:keystore文件的位置通常情況下和項(xiàng)目的根目錄相關(guān),但是也能夠是絕對(duì)目錄,雖然這并不被推薦(除非是debug的,因?yàn)樗鼤?huì)自動(dòng)被創(chuàng)建)。
      注意3:如果你把這些文件納入到版本控制系統(tǒng)中,你可能并不想要把密碼放在其中。這里介紹了從控制臺(tái)或環(huán)境變量中讀取值的方法。

      3.依賴,Android庫(kù)以及多項(xiàng)目建立

      3.1依賴二進(jìn)制包

      3.1.1本地包

      要去配置一個(gè)依賴庫(kù)或者額外的jar庫(kù),你需要在compile配置中添加一個(gè)依賴關(guān)系。下面的片段在libs文件夾中添加了所有jar文件的依賴關(guān)系:

      dependencies {
          compile fileTree(dir: 'libs', include: ['*.jar'])
      }
      
      
      android {
          //...
      }
      

      注意:dependencies特定領(lǐng)域語(yǔ)言元素是標(biāo)準(zhǔn)Gradle API中的一部分。在這里面的每一項(xiàng)都被加入到編譯類路徑中,并都在最終的APK文件中被打包進(jìn)去。以下是可能的配置信息:

      • compile 主應(yīng)用
      • androidTestCompile 測(cè)試應(yīng)用
      • debugCompile debug構(gòu)建類型
      • releaseCompile release構(gòu)建類型

      由于在構(gòu)建APK時(shí)并不可能沒(méi)有關(guān)聯(lián)的構(gòu)建類型,因此APK總是被配置至少兩個(gè)編譯配置信息:compile以及構(gòu)建類型Compile。創(chuàng)建一個(gè)新的構(gòu)建類型將會(huì)自動(dòng)創(chuàng)建一個(gè)基于該構(gòu)建類型名稱的編譯配置。如果debug版本需要添加一個(gè)自定義的庫(kù)(如報(bào)告程序崩潰情況)時(shí),或者不同構(gòu)建類型依賴于相同庫(kù)的不同版本時(shí)這將是非常有用的(點(diǎn)擊這里詳見不同版本的沖突是如何處理的)。

      3.1.2遠(yuǎn)程依賴

      Gradle支持從Maven和Ivy庫(kù)中拉取依賴(artifact)。首先,該倉(cāng)庫(kù)必須被添加到列表中,其次依賴必須被聲明。

      repositories {
           jcenter()
      }
      
      
      dependencies {
          compile 'com.google.guava:guava:18.0'
      }
      
      
      android {
          //...
      }
      

      注意1:jcenter()是指定倉(cāng)庫(kù)的URL縮寫。Gradle同時(shí)支持遠(yuǎn)程和本地的倉(cāng)庫(kù)。
      注意2:Gradle遵循依賴的傳遞性。這意味著,如果如果一個(gè)依賴,依賴于其本身,這也會(huì)被拉取。

      關(guān)于建立依賴的更多信息,請(qǐng)閱讀Gradle使用指南DSL文檔

      3.2多項(xiàng)目的搭建

      Gradle項(xiàng)目也能夠通過(guò)多項(xiàng)目搭建依賴于其他Gradle項(xiàng)目。一個(gè)多項(xiàng)目的搭建通常為將所有項(xiàng)目作為已給項(xiàng)目根目錄的子目錄。例如,給出如下的結(jié)構(gòu):
      MyProject/

      • app/
      • libraries/
        • lib1/
        • lib2/
          我們能夠識(shí)別出三個(gè)項(xiàng)目。Gradle會(huì)用下述的命名進(jìn)行參考:
          :app
          :libraries:lib1
          :libraries:lib2
          每一個(gè)項(xiàng)目擁有其自己的build.gradle文件,聲明了其如何得到其構(gòu)建。額外的,將會(huì)有一個(gè)被命名為setting.gradle的文件位于根目錄,用于聲明所有項(xiàng)目。一下給出了結(jié)構(gòu):
          MyProject/
          | settings.gradle
      • app/
        | build.gradle
      • libraries/
        • lib1/
          | build.gradle
        • lib2/
          | build.gradle

      setting.gradle的內(nèi)容非常簡(jiǎn)單。它定義了哪個(gè)文件夾是一個(gè)Gradle項(xiàng)目:

      include ':app', ':libraries:lib1', ':libraries:lib2'
      

      :app項(xiàng)目很可能依賴于其他的項(xiàng)目作為庫(kù),這是通過(guò)以下聲明實(shí)現(xiàn)的:

      dependencies {
           compile project(':libraries:lib1')
      }
      

      關(guān)于多項(xiàng)目搭建的更多信息,請(qǐng)點(diǎn)擊這里。

      3.3庫(kù)項(xiàng)目

      在上述的多項(xiàng)目搭建中:libraries:lib1:libraries:lib2作為Java項(xiàng)目,:appAndroid項(xiàng)目將會(huì)使用這兩個(gè)項(xiàng)目的jar輸出。但是,如果你想要通過(guò)Android API或使用Android風(fēng)格的資源來(lái)共享代碼,這些庫(kù)就不能是常規(guī)的Java項(xiàng)目,它們必須是Android庫(kù)項(xiàng)目。

      3.3.1創(chuàng)建一個(gè)庫(kù)項(xiàng)目

      一個(gè)庫(kù)項(xiàng)目和一個(gè)常規(guī)的Android項(xiàng)目非常相似。因?yàn)闃?gòu)建庫(kù)和構(gòu)建應(yīng)用是不同的,因此使用的插件也不同。本質(zhì)上來(lái)說(shuō),兩個(gè)插件大多數(shù)代碼都是相似的,并且都由相同的com.android.tools.build.gradlejar文件提供。

      buildscript {
          repositories {
              jcenter()
          }
      
      
          dependencies {
              classpath 'com.android.tools.build:gradle:1.3.1'
          }
      }
      
      
      apply plugin: 'com.android.library'
      
      
      android {
          compileSdkVersion 23
          buildToolsVersion "23.0.1"
      }
      

      這將會(huì)創(chuàng)建一個(gè)使用API 23進(jìn)行編譯的庫(kù)項(xiàng)目。資源集,構(gòu)建類型以及依賴關(guān)系的使用都和應(yīng)用項(xiàng)目相同,并可以通過(guò)相同的方式自定義。

      3.3.2項(xiàng)目和項(xiàng)目庫(kù)的區(qū)別

      庫(kù)項(xiàng)目的主要輸出是一個(gè).arr包(表示Android archive),是編譯代碼(就像jar文件或者原生的.so文件一樣)和資源文件(清單,res文件以及assets文件)的組合。一個(gè)庫(kù)項(xiàng)目也可以生成一個(gè)測(cè)試apk文件用于測(cè)試庫(kù)的獨(dú)立性。對(duì)此使用的祖先任務(wù)也是相同的(assembleDebugassembleReleas)。因此用命令去構(gòu)建這樣一個(gè)項(xiàng)目并沒(méi)有什么區(qū)別。對(duì)于其他方面,庫(kù)項(xiàng)目表現(xiàn)得和應(yīng)用項(xiàng)目一樣。庫(kù)項(xiàng)目也擁有構(gòu)建類型和產(chǎn)品渠道(product flavors,見下文),并且能夠潛在地生成多個(gè)版本的aar文件。請(qǐng)注意,構(gòu)建類型的大多數(shù)配置并不能夠用于庫(kù)項(xiàng)目。但是你可以使用自定義資源集來(lái)改變庫(kù)的內(nèi)容,這取決于當(dāng)前庫(kù)是否被用于一個(gè)項(xiàng)目,或者用于被測(cè)試。

      3.3.4引用一個(gè)庫(kù)

      引用一個(gè)庫(kù)和二進(jìn)制包被引用是一樣的:

      dependencies {
          compile project(':libraries:lib1')
          compile project(':libraries:lib2')
      }
      

      注意:如果你有多個(gè)庫(kù),那么引用的順序就變得很重要。這和舊的構(gòu)建系統(tǒng)中在project.properties文件中的依賴順序一樣重要。

      3.3.5庫(kù)發(fā)布

      默認(rèn)情況下,一個(gè)庫(kù)僅僅發(fā)布其release版本。該版本被用于所有項(xiàng)目對(duì)庫(kù)的引用,不論這些項(xiàng)目本身使用怎樣的的構(gòu)建類型,而這是一個(gè)我們將要取消的臨時(shí)限制。你可以控制要發(fā)布何種版本:

      android {
          defaultPublishConfig "debug"
      }
      

      注意,發(fā)布的配置名參考于版本的命名。Release和Debug版僅僅適合沒(méi)有渠道的情況下。如果你想要使用渠道改變默認(rèn)的發(fā)布版本,你可以這樣寫:

      android {
          defaultPublishConfig "flavor1Debug"
      }
      

      發(fā)布一個(gè)庫(kù)的所有版本是可能的。我們計(jì)劃允許使用一個(gè)標(biāo)準(zhǔn)的項(xiàng)目到項(xiàng)目的依賴,但是目前這是不可能的,這是因?yàn)镚radle中的一些限制(我們正在努力解決這些)。
      發(fā)布所有版本在默認(rèn)情況下是不可以的。下面的片段展示了如何開啟這項(xiàng)功能:

      android {
          publishNonDefault true
      }
      

      很重要的一點(diǎn)是,你需要意識(shí)到發(fā)布多版本的arr文件而不是包含多個(gè)版本的arr文件。每一個(gè)arr包包含單個(gè)版本。發(fā)布一個(gè)版本意味著使得這個(gè)arr文件和Gradle項(xiàng)目輸出的依賴一樣可用。這能夠被用于當(dāng)發(fā)布到maven庫(kù)時(shí),或者當(dāng)另一個(gè)項(xiàng)目依賴于該庫(kù)時(shí)。
      Gradle有一個(gè)默認(rèn)依賴的概念。這是當(dāng)我們這樣寫時(shí):

      dependencies {
          compile project(':libraries:lib2')
      }
      

      創(chuàng)建一個(gè)依賴于另一個(gè)發(fā)布類庫(kù)的類庫(kù)時(shí),你需要指定使用哪一個(gè):

      dependencies {
          flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
          flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
      }
      

      重點(diǎn)1:請(qǐng)注意到已發(fā)布的配置是全版本的,包括所有的構(gòu)建類型,并且需要被引用。
      重點(diǎn)2:當(dāng)開啟非默認(rèn)發(fā)布時(shí),maven發(fā)布插件將會(huì)發(fā)布這些額外的版本作為額外的包(帶有classifier)。這意味著發(fā)布到maven庫(kù)并不能真正地兼容。你應(yīng)該發(fā)布一個(gè)單版本,或者開啟所有的配置用于發(fā)布內(nèi)部項(xiàng)目依賴。

      4.測(cè)試

      應(yīng)用項(xiàng)目中整合了測(cè)試應(yīng)用的構(gòu)建。因此不需要再有一個(gè)獨(dú)立的測(cè)試項(xiàng)目。

      4.1單元測(cè)試

      在1.1中所提到的單元測(cè)試支持,請(qǐng)點(diǎn)擊這里。本章節(jié)的剩下部分介紹了“工具測(cè)試(instrumentation tests)”,能夠運(yùn)行在真機(jī)或者模擬機(jī)上,其要求是要構(gòu)建一個(gè)測(cè)試APK文件。

      4.2基礎(chǔ)配置

      如之前所提到的,main資源集后面就是androidTest資源集,默認(rèn)情況下位于src/androidTest,使用這個(gè)資源集使得測(cè)試APK被構(gòu)建并能夠安裝到設(shè)備中,從而可以使用Android測(cè)試框架來(lái)測(cè)試應(yīng)用,包括Android單元測(cè)試,instrumentation tests以及uiautomator tests。清單中的<instrumentation>節(jié)點(diǎn)是被生成的,但是你可以創(chuàng)建一個(gè)src/androidTest/AndroidManifest.xml文件來(lái)添加測(cè)試清單(manifest)的其他組件。
      還有一些值能夠在instrumentation測(cè)試應(yīng)用中配置。(詳情請(qǐng)查閱DSL參考

      • testApplicationId
      • testInstrumentationRunner
      • testHandleProfiling
      • testFunctionalTest

      如前所述,上述信息被配置在defaultConfig對(duì)象:

      android {
          defaultConfig {
              testApplicationId "com.test.foo"        testInstrumentationRunner "android.test.InstrumentationTestRunner"
              testHandleProfiling true 
              testFunctionalTest true
          }
      }
      

      測(cè)試應(yīng)用清單文件的instrumentation節(jié)點(diǎn)中targetPackage屬性的值自動(dòng)化填充為測(cè)試應(yīng)用的包名。即使在defaultConfig中或者在構(gòu)建類型對(duì)象中自定義,該值并不會(huì)發(fā)生改變。這也就是清單文件被自動(dòng)生成的部分原因。
      另外,androidTest資源集能夠配置自己的依賴關(guān)系。默認(rèn)情況下,應(yīng)用和其自身的依賴被添加到測(cè)試app的類路徑中,但是可以使用下面的片段進(jìn)行擴(kuò)展:

      dependencies {
          androidTestCompile 'com.google.guava:guava:11.0.2'
      }
      

      測(cè)試app是由assembleAndroidTest任務(wù)構(gòu)建的。這并不是對(duì)主assemble任務(wù)的依賴,而是當(dāng)測(cè)試準(zhǔn)備運(yùn)行時(shí)自動(dòng)調(diào)用的。
      當(dāng)前只有一個(gè)構(gòu)建類型能夠被測(cè)試。默認(rèn)情況下是debug構(gòu)建類型。但是可以進(jìn)行如下配置:

      android {
          //...
          testBuildType "staging"
      }
      

      4.3解決主apk和測(cè)試apk之間的沖突

      當(dāng)instrumentation測(cè)試運(yùn)行時(shí),主APK和測(cè)試APK共享相同的類路徑。如果主APK和測(cè)試APK使用相同的庫(kù)(如Guava)的不同版本時(shí),Gradle構(gòu)建會(huì)失敗。如果gradle并不捕獲這一點(diǎn),你的應(yīng)用會(huì)在測(cè)試版和正常版表現(xiàn)地不同(包括任何會(huì)崩潰的情況)。
      為了讓應(yīng)用構(gòu)建成功,請(qǐng)確保兩個(gè)APK都使用相同版本的庫(kù)。如果錯(cuò)誤來(lái)自于間接依賴(在你自己的build.gradle中沒(méi)有聲明的庫(kù)),僅僅在需要的地方(compile或者androidTestCompile)添加最新的依賴即可。你也可以使用Gradle解決沖突機(jī)制。你可以通過(guò)運(yùn)行以下代碼檢查依賴樹:./gradlew :app:dependencies./gradlew :app:androidDependencies。

      4.4運(yùn)行測(cè)試

      如前所述,check任務(wù)需要一個(gè)連接的設(shè)備,并通過(guò)祖先任務(wù)connnectedCheck啟動(dòng)。這個(gè)任務(wù)會(huì)依賴connectedDebugAndroidTest。這個(gè)任務(wù)做了以下幾件事:

      • 確保app和測(cè)試app被構(gòu)建(依賴于assembleDebugassembleDebugAndroidTest)。
      • 安裝兩款應(yīng)用
      • 運(yùn)行測(cè)試
      • 卸載兩款應(yīng)用

      如果有多個(gè)設(shè)備連接,所有的測(cè)試都會(huì)平行運(yùn)行在所有連接的設(shè)備上。如果其中一個(gè)測(cè)試失敗,在任何設(shè)備中,構(gòu)建都將會(huì)失敗。

      4.5測(cè)試Android庫(kù)

      測(cè)試Android庫(kù)項(xiàng)目和測(cè)試Android應(yīng)用項(xiàng)目是完全相同的。唯一的區(qū)別在于,整個(gè)庫(kù)以及依賴作為測(cè)試app的一個(gè)庫(kù)被自動(dòng)添加。結(jié)果是,測(cè)試APK不僅僅包括了自身的代碼,也包含了庫(kù)本身及其依賴。androidTest任務(wù)變成僅僅安裝(卸載)測(cè)試APK(因?yàn)闆](méi)有其他APK可供安裝)。

      4.6測(cè)試報(bào)告

      當(dāng)運(yùn)行單元測(cè)試時(shí),Gradle輸出一個(gè)HTML格式的報(bào)告可供輕松地查看結(jié)果。Android插件構(gòu)建并拓展HTML報(bào)告用于從所有連接設(shè)備中匯集。所有的測(cè)試結(jié)果以xml文件的形式存儲(chǔ)在build/reports/androidTests/中(和常規(guī)的jNnit存儲(chǔ)在build/reports/tests相似)。該路徑可配置如下:

      android {
          //...
          testOptions {
              resultsDir = "${project.buildDir}/foo/results"
          }
      }
      

      android.testOptions.resultsDir的值請(qǐng)參考:Project.file(String)

      4.6.1多項(xiàng)目報(bào)告

      在帶有多應(yīng)用和多庫(kù)的多項(xiàng)目的搭建中,當(dāng)同時(shí)運(yùn)行所有測(cè)試時(shí),可能生成一個(gè)所有測(cè)試的測(cè)試報(bào)告是很有用的。
      為了做到這一點(diǎn),可用一個(gè)不同的gradle插件:

      buildscript {
          repositories {
              jcenter()
          }
      
      
          dependencies {
              classpath 'com.android.tools.build:gradle:0.5.6'
          }
      }
      
      
      apply plugin: 'android-reporting'
      

      這應(yīng)該被用在根項(xiàng)目中,也就是setting.gradle旁邊的build.gradle。
      之后,從根文件夾開,以下的命令將會(huì)運(yùn)行所有的測(cè)試并匯集成報(bào)告:
      gradle deviceCheck mergeAndroidReports --continue

      注意:--continue選項(xiàng)確保了所有子目錄在內(nèi)的所有測(cè)試都能夠被運(yùn)行,即使其中有失敗的情況。

      4.7Lint支持

      你可以在一個(gè)指定版本運(yùn)行l(wèi)int檢查(如下),例如:./gradlew lintRelease或者全版本的lint檢查(./gradlew lint),在這種情況下會(huì)產(chǎn)生一個(gè)描述指定版本的報(bào)告。你可以通過(guò)添加lintOption部分來(lái)配置lint(如下)。你應(yīng)該添加一些典型的部分:詳見。

      android {
          lintOptions {
              // turn off checking the given issue id's
              disable 'TypographyFractions','TypographyQuotes'
      
              // turn on the given issue id's
              enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
      
              // check *only* the given issue id's
              check 'NewApi', 'InlinedApi'
          }
      }
      

      5.構(gòu)建版本

      新構(gòu)建系統(tǒng)的一個(gè)目標(biāo)就是能夠?qū)ν粋€(gè)應(yīng)用創(chuàng)建不同的版本。
      主要使用情況有兩個(gè):

      1. 一個(gè)應(yīng)用的不同版本。例如,一個(gè)免費(fèi)/demo版本和一個(gè)專業(yè)版本
      2. 同一個(gè)應(yīng)用在Google Play商店打包分發(fā)多個(gè)詳見:http://developer./google/play/publishing/multiple-apks.html
      3. 前兩者的組合

      目標(biāo)是能夠在同一個(gè)項(xiàng)目中生成不同的應(yīng)用,而不是使用同一個(gè)庫(kù)的不同應(yīng)用項(xiàng)目。

      5.1產(chǎn)品渠道

      產(chǎn)品渠道(product flavor)定義了一個(gè)項(xiàng)目應(yīng)用構(gòu)建的自定義版本。單個(gè)的項(xiàng)目可以有不同的渠道,從而生成的應(yīng)用不同。
      這個(gè)新的概念被設(shè)計(jì)用于幫助版本差異非常小的情況下。如果當(dāng)問(wèn)到“這是否是同一個(gè)應(yīng)用?”時(shí),如果是,那么通過(guò)庫(kù)項(xiàng)目去實(shí)現(xiàn)可能更適合一些。
      產(chǎn)品渠道通過(guò)一個(gè)叫做productFlavors的特定領(lǐng)域容器聲明:

      android {
          //....
      
      
          productFlavors {
              flavor1 {
                  //...         
              }
      
      
              flavor2 {
                  ...
              }
          }
      }
      

      上例中將會(huì)創(chuàng)建兩個(gè)渠道,分別是flavor1flavor2

      注意:渠道的名稱不能喝已經(jīng)存在的構(gòu)建類型名稱沖突,也不能使用androidTesttest資源集的名稱。

      5.2構(gòu)建類型+產(chǎn)品渠道=構(gòu)建版本

      正如我們前面所看到的,每一個(gè)構(gòu)建類型生成一個(gè)新的APK文件。產(chǎn)品渠道也是相同的:項(xiàng)目的輸出變成所有可能構(gòu)建類型和產(chǎn)品渠道的組合。每一個(gè)(構(gòu)建類型,產(chǎn)品渠道)組合被稱為構(gòu)建版本。例如,在默認(rèn)的debugrelease構(gòu)建類型中,上面的例子可以生成四個(gè)構(gòu)建版本:

      • Flavor1 - debug
      • Flavor1 - release
      • Flavor2 - debug
      • Flavor2 - release

      沒(méi)有渠道的項(xiàng)目依然擁有構(gòu)建版本,使用的是單個(gè)默認(rèn)的default渠道/配置.

      5.3產(chǎn)品渠道配置

      每一個(gè)渠道的完整配置如下:

      android {
          //...
      
      
          defaultConfig {
              minSdkVersion 8
              versionCode 10
          }
      
      
          productFlavors {
              flavor1 {
                  applicationId "com.example.flavor1"
                  versionCode 20
               }
      
               flavor2 {
                   applicationId "com.example.flavor2"
                   minSdkVersion 14
               }
          }
      }
      

      注意到android.productFlavors.*對(duì)象是ProductFlavor,其類型和android.defaultConfig對(duì)象類型相同。這意味著它們共享相同的屬性。
      defaultConfig為所有的渠道提供了基礎(chǔ)的配置,每一個(gè)種渠道能夠覆蓋它的任何值。在上述的例子中,配置信息以如下結(jié)尾:

      • flavor1
        • applicationId: com.example.flavor1
        • minSdkVersion: 8
        • versionCode: 20
      • flavor2
        • applicationId: com.example.flavor2
        • minSdkVersion: 14
        • versionCode: 10

      通常情況下,構(gòu)建類型配置會(huì)覆蓋其他配置。例如,構(gòu)建類型的applicationIdSuffix追加在產(chǎn)品渠道的applicationId后面。有一些在構(gòu)建類型和產(chǎn)品渠道都能夠設(shè)置的情況。在這種情況下,例如signingConfig就是這種屬性。這使得所有發(fā)布包共享這些簽名配置。通過(guò)設(shè)置android.buildTypes.release.signingConfig或者對(duì)每一個(gè)包通過(guò)設(shè)置自己的android.productFlavors.*.signingConfig來(lái)分別使用簽名配置。

      5.4資源集和依賴

      和構(gòu)建類型相似,產(chǎn)品渠道也是通過(guò)自己的資源集來(lái)貢獻(xiàn)代碼。上述的例子創(chuàng)建了四個(gè)資源集:

      • android.sourceSets.flavor1 位置為src/flavor1

      • android.sourceSets.flavor2位置為src/flavor2/

      • android.sourceSets.androidTestFlavor1位置為 src/androidTestFlavor1/

      • android.sourceSets.androidTestFlavor2位置為 src/androidTestFlavor2/
        這些資源集通過(guò)構(gòu)建類型和android.sourceSets.main被用于構(gòu)建APK。下面的規(guī)則用于處理所有被用于構(gòu)建單個(gè)APK的情況:

      • 所有的代碼(src/*/java)共同用于多文件夾來(lái)生成單個(gè)輸出。

      • 清單被共同合并到單個(gè)的清單中。這允許產(chǎn)品渠道擁有不同的組件、權(quán)限,和構(gòu)建類型相似。

      • 所有的資源遵循覆蓋的優(yōu)先級(jí)。構(gòu)建類型覆蓋產(chǎn)品渠道,產(chǎn)品渠道覆蓋main資源集。

      • 每個(gè)構(gòu)建版本生成自己的R類。各個(gè)版本直接不存在共享。

      最后,和構(gòu)建類型一樣,產(chǎn)品渠道可以擁有自己的依賴。例如,如果渠道用于生成基于廣告的app或者付費(fèi)的app,每一個(gè)渠道擁有自己的廣告sdk依賴。

      dependencies {
          flavor1Compile "..."
      }
      

      在這個(gè)例子中,文件src/flavor1/AndroidManifest.xml可能需要包含網(wǎng)絡(luò)權(quán)限
      每個(gè)版本同樣也創(chuàng)建了額外的資源集:

      • android.sourceSets.flavor1Debug位于src/flavor1Debug
      • android.sourceSets.flavor1Release位于src/flavor1Release
      • android.sourceSets.flavor2Debug位于src/flavor2Debug
      • android.sourceSets.flavor2Release位于src/flavor2Release

      他們比構(gòu)建類型擁有更高的優(yōu)先級(jí),并且允許自定義版本等級(jí)。

      5.5構(gòu)建和任務(wù)

      我們之前看到的,每一種構(gòu)建類型創(chuàng)建自己的assmble名字任務(wù),但是構(gòu)建版本是構(gòu)建類型和產(chǎn)品渠道的組合。
      當(dāng)使用產(chǎn)品類型時(shí),更多的任務(wù)會(huì)被創(chuàng)建,如:

      1. assemble構(gòu)建版本名
      2. assemble構(gòu)建類型名
      3. assemble產(chǎn)品渠道名

      第1項(xiàng)允許你直接構(gòu)建單個(gè)的版本,例如aseembleFlavor1Debug。

      第2項(xiàng)允許你構(gòu)建所有已給構(gòu)建類型的apk文件。例如assembleDebug將會(huì)構(gòu)建flavor1Debugflavor2Debug。

      第3項(xiàng)允許你構(gòu)建給定渠道的所有APK文件。例如,assembleFlavor1將會(huì)構(gòu)建assembleFlavor1DebugassembleFlavor1Release。

      任務(wù)assemble會(huì)構(gòu)建有可能的版本。

      5.6多渠道版本

      在一些情況下,可能會(huì)想要基于多種條件下創(chuàng)建相同應(yīng)用的多個(gè)版本。
      考慮一個(gè)游戲作為例子,該游戲有一個(gè)demo版本和一個(gè)付費(fèi)版本并且想要使用多apk支持中的ABI過(guò)濾條件。3個(gè)ABI和2個(gè)版本需要生成6個(gè)APK文件(不考慮構(gòu)建類型)。
      但是,支付版本的代碼對(duì)于相對(duì)應(yīng)的3個(gè)ABI版本是相同的,因此創(chuàng)建6個(gè)渠道并不是一個(gè)好方法。
      取而代之的是,配置兩個(gè)渠道版本,所有的構(gòu)建版本應(yīng)該自動(dòng)構(gòu)建可能的組合。
      這個(gè)功能是通過(guò)渠道規(guī)格(flavor dimension)來(lái)實(shí)現(xiàn)的。渠道被設(shè)置到指定的規(guī)格:

      android {
          //...
      
      
          flavorDimensions "abi", "version"
      
      
          productFlavors {
              freeapp {
                  dimension "version"
                  //...
              }
      
              paidapp {
                  dimension "version"
                  ...
              }
      
      
              arm {
                  dimension "abi"
                  ...
              }
              
              mips {
                  dimension "abi"
                  ...
              }
      
             x86 {
                 dimension "abi"
                  ...
              }
          }
      }
      

      android.flavorDimensions數(shù)組定義了可能的規(guī)格。每一個(gè)產(chǎn)品渠道指定一個(gè)規(guī)格。
      從指定了規(guī)格的產(chǎn)品渠道(free app,paid app)以及構(gòu)建類型(debug,release),能夠創(chuàng)建如下的構(gòu)建版本:

      • x86-freeapp-debug
      • x86-freeapp-release
      • arm-freeapp-debug
      • arm-freeapp-release
      • mips-freeapp-debug
      • mips-freeapp-release
      • x86-paidapp-debug
      • x86-paidapp-release
      • arm-paidapp-debug
      • arm-paidapp-release
      • mips-paidapp-debug
      • mips-paidapp-release

      規(guī)格的順序是通過(guò)android.flavorDimensions定義的,這一點(diǎn)非常重要。
      每一個(gè)版本通過(guò)不同的產(chǎn)品渠道進(jìn)行配置:

      • android.defaultConfig
      • abi規(guī)格
      • 版本規(guī)格

      規(guī)格的順序驅(qū)動(dòng)了是哪個(gè)渠道去覆蓋哪個(gè)渠道,這對(duì)于渠道的哪個(gè)資源值去替代另一個(gè)渠道的資源值而言非常重要。
      渠道規(guī)格通過(guò)高優(yōu)先級(jí)進(jìn)行定義。在這種情況下:

      abi>version>defaultConfig
      多渠道項(xiàng)目也擁有額外的資源集,和構(gòu)建版本資源集相似但是不包括構(gòu)建類型:

      • android.sourceSets.x86Freeapp位于src/x86Freeapp
      • android.sourceSets.armPaidapp位于src/armPaidapp

      這樣允許渠道組合級(jí)別的自定義。他們比基本的渠道資源集擁有更高的優(yōu)先級(jí),但是優(yōu)先級(jí)低于構(gòu)建類型資源集。

      5.7測(cè)試

      多渠道項(xiàng)目測(cè)試和簡(jiǎn)單的項(xiàng)目測(cè)試非常相似。
      androidTest資源集用于所有渠道的通用測(cè)試,而每個(gè)渠道可以有自己的測(cè)試。
      如上所提及的,每個(gè)渠道的資源集按照如下形式被創(chuàng)建:

      • android.sourceSets.androidTestFlavor1位于src/androidTestFlavor1
      • android.sourceSets.androidTestFlavor2位于src/androidTestFlavor2/
        相似地,它們可以有各自的依賴:
      dependencies {
          androidTestFlavor1Compile "..."
      }
      

      運(yùn)行測(cè)試可以通過(guò)祖先任務(wù)deviceCheck完成,或者通過(guò)主androidTest任務(wù)。
      每一個(gè)渠道都有自己的測(cè)試任務(wù):androidTest版本名,例如:

      • androidTestFlavor1Debug
      • androidTestFlavor2Debug

      相似地,測(cè)試APK的構(gòu)建和卸載安裝按照每個(gè)版本進(jìn)行:

      • assembleFlavor1Test
      • installFlavor1Debug
      • installFlavor1Test
      • uninstallFlavor1Debug

      最后,HTML報(bào)告生成支持通過(guò)渠道的匯總。
      測(cè)試結(jié)果和報(bào)告的位置如下所示,首先是渠道版,其次是匯總版:

      • build/androidTest-results/flavors/渠道名
      • build/androidTest-results/all/
      • build/reports/androidTests/flavors/渠道名
      • build/reports/androidTests/all/

      或者可以自定義路徑,但這僅僅改變了文件夾的根目錄,但是仍然會(huì)對(duì)每個(gè)渠道創(chuàng)建子目錄并匯集報(bào)告結(jié)果。

      5.8構(gòu)建配置

      Android Studio生成一個(gè)叫作BuildConfig的類,包含了用于構(gòu)建一個(gè)特定版本的常量值。你可以指定這些常量值來(lái)改變不同版本,例如:

      private void javaCode() {
          if (BuildConfig.FLAVOR.equals("paidapp")) {
              doIt();
          else {
              showOnlyInPaidAppDialog();
          }
      }
      
      

      以下是構(gòu)建配置中含有的值:

      • boolean DEBUG – if the build is debuggable.
      • int VERSION_CODE
      • String VERSION_NAME
      • String APPLICATION_ID
      • String BUILD_TYPE - 構(gòu)建類型的名字,例如”release”
      • String FLAVOR – 渠道名稱,例如”paid app”

      如果項(xiàng)目使用渠道規(guī)格,將會(huì)生成額外的規(guī)格。使用上面的例子,會(huì)有如下的構(gòu)建配置示例:

      • String FLAVOR = "armFreeapp"
      • String FLAVOR_abi = "arm"
      • String FLAVOR_version = "free app"

      5.9過(guò)濾版本

      當(dāng)你添加規(guī)格和渠道時(shí),你應(yīng)該停止使用沒(méi)有意義的版本。例如你可能為了更快的測(cè)試,會(huì)定義一個(gè)使用你的Web API的渠道,以及一個(gè)使用硬編碼的假數(shù)據(jù)。第二個(gè)渠道僅僅在開發(fā)的時(shí)候有用,但是在發(fā)布版本的構(gòu)建時(shí)卻沒(méi)有用處。你可以刪除這個(gè)版本,改成使用variantFilter,例如:

      android {
          productFlavors {
              realData
              fakeData
          }
      
          variantFilter { variant ->
              def names = variant.flavors*.name
      
              if (names.contains("fakeData") && variant.buildType.name == "release") {
                  variant.ignore = true
              }
          }
      }
      

      在上面的配置中,你的項(xiàng)目只有三個(gè)版本:

      • realDataDebug
      • realDataRelease
      • fakeDataDebug

      6.高級(jí)構(gòu)建自定義

      6.1運(yùn)行混淆

      混淆插件在Android插件中被自動(dòng)使用,如果構(gòu)建類型通過(guò)minifyEnabled屬性開啟了混淆,那么任務(wù)會(huì)被自動(dòng)創(chuàng)建。

      android {
          buildTypes {
              release {
                  minifyEnabled true
                  proguardFile getDefaultProguardFile('proguard-android.txt')
              }
          }
      
         productFlavors {
              flavor1 {
              }
              flavor2 {            proguardFile 'some-other-rules.txt'        
              }
      
          }
      }
      

      版本使用所有在這個(gè)構(gòu)建類型以及產(chǎn)品渠道中聲明的規(guī)則文件。
      有兩個(gè)默認(rèn)規(guī)則文件:

      • proguard-android.txt
      • proguard-android-potimize.txt

      這些文件位于SDK中。使用getDefaultProguardFile()會(huì)返回文件的全路徑。這些文件是相同的,除非開啟了優(yōu)化。

      6.2縮減資源

      你可以在構(gòu)建時(shí)自動(dòng)移除所有未使用的資源。關(guān)于更多信息,請(qǐng)查閱資源縮減文檔。

      6.3操作任務(wù)

      基本的Java項(xiàng)目擁有有限的任務(wù)集共同創(chuàng)建輸出。
      classes是編譯java源代碼的任務(wù)之一,縮寫為:project.tasks.classes。
      在Android項(xiàng)目中有一些復(fù)雜。這是因?yàn)榭赡苡写罅肯嗤娜蝿?wù),并且它們的名字基于產(chǎn)品渠道和構(gòu)建類型命名。
      為了去解決這一點(diǎn),android對(duì)象有以下兩個(gè)屬性:

      • applicationVariants(只用于app插件)
      • libraryVariants(只用于庫(kù)插件)
      • testVariants(同時(shí)適用于app和庫(kù)插件)

      三者分別返回ApplicationVariant,LibraryVariant,TestVariant領(lǐng)域?qū)ο蠹?/a>。

      注意到,訪問(wèn)以上三種集合的任意一種都會(huì)引發(fā)所有任務(wù)的創(chuàng)建。這意味著在訪問(wèn)集合后不會(huì)發(fā)生任何重新配置的情況。
      領(lǐng)域?qū)ο蠹现苯釉L問(wèn)所有對(duì)象,或者通過(guò)更方便的過(guò)濾器。

      android.applicationVariants.all { variant ->
         ....
      }
      

      所有版本類都含有以下屬性:

      1. name 類型為String,表示版本名稱,要求不重復(fù)。
      2. description 類型為String,人類可讀的版本描述。
      3. dirName 類型為String,版本的子文件夾名稱,要求不重復(fù)??赡軙?huì)有多個(gè)文件夾,例如”debug/flavor”。
      4. baseName 類型為String,輸出版本的基本名稱,要求不重復(fù)。
      5. outputFile 類型為File,版本的輸出。擁有讀/寫屬性。
      6. processManifest 類型為ProcessManifest,用于處理清單的任務(wù)。
      7. aidlCompile 類型為AidlCompile,編譯AIDL文件的任務(wù)。
      8. renderscriptCompile 類型為RenderscriptCompile,編譯Renderscript的任務(wù)。
      9. mergeResources 類型為MergeResources,合并資源文件的任務(wù)。
      10. mergeAssets 類型為MergeAssets,合并assets的任務(wù)。
      11. processResources 類型為ProcessAndroidResources,用于處理和編譯資源的任務(wù)。
      12. generateBuildConfig 類型為GenerateBuildConfig,生成BuildConfig類的任務(wù)
      13. javaCompile 類型為JavaCompile,編譯Java代碼的任務(wù)。
      14. processJavaResources 類型為Copy,處理Java資源的任務(wù)。
      15. assemble 類型為DefaultTask,對(duì)版本輸出的祖先任務(wù)。
        ApplicationVariant類添加了如下內(nèi)容:
      16. buildType 類型為BuildType,版本的構(gòu)建類型。
      17. productFlavors 類型為L(zhǎng)ist<ProductFlavor>,版本的產(chǎn)品渠道可以不設(shè)置但是永遠(yuǎn)不為空。
      18. mergedFlavor 類型為ProductFlavor,android.defaultConfig和variant.productFlavors的合并。
      19. signingConfig 類型為SigningConfig,該版本的簽名配置。
      20. isSigningReady 類型為boolean。為真時(shí)該版本擁有簽名的所有必需信息。
      21. testVariant 類型為BuildVariant。TestVariant會(huì)測(cè)試該版本。
      22. dex 類型為Dex,編譯代碼的任務(wù)。如果是個(gè)庫(kù)項(xiàng)目可以為空。
      23. packageApplication 類型為PackageApplication,構(gòu)建最終APK的任務(wù)。如果是個(gè)庫(kù)項(xiàng)目可以為空。
      24. zipAlign 類型為ZipAlign。打包apk的任務(wù),如果是個(gè)庫(kù)項(xiàng)目或者APK不能被簽名時(shí)可以為空。
      25. install 類型為DefaultTask,安裝任務(wù),可以為空。
      26. unstall 類型為DefaultTask,卸載任務(wù)。
        LibraryVariant類添加了一下內(nèi)容:
      27. buildType 類型為BuildType,版本的構(gòu)建類型。
      28. mergedFlavor 類型為ProductFlavor,默認(rèn)配置值。
      29. testVariant 類型為BuildVariant,要測(cè)試的構(gòu)建版本。
      30. packageLibrary 類型為Zip,打包庫(kù)AAR壓縮包的任務(wù),如果不是庫(kù)項(xiàng)目則為空。
        TestVariant類添加了如下內(nèi)容:
      31. buildType 類型為BuildType,版本的構(gòu)建類型。
      32. productFlavors 類型為L(zhǎng)ist<ProductFlavor>,版本的產(chǎn)品渠道可以不設(shè)置但是永遠(yuǎn)不為空。
      33. mergedFlavor 類型為ProductFlavor,android.defaultConfig和variant.productFlavors的合并。
      34. signingConfig 類型為SigningConfig,該版本的簽名配置。
      35. isSigningReady 類型為boolean。為真時(shí)該版本擁有簽名的所有必需信息。
      36. testVariant 類型為BuildVariant。TestVariant會(huì)測(cè)試該版本。
      37. dex 類型為Dex,編譯代碼的任務(wù)。如果是個(gè)庫(kù)項(xiàng)目可以為空。
      38. packageApplication 類型為PackageApplication,構(gòu)建最終APK的任務(wù)。如果是個(gè)庫(kù)項(xiàng)目可以為空。
      39. zipAlign 類型為ZipAlign。打包apk的任務(wù),如果是個(gè)庫(kù)項(xiàng)目或者APK不能被簽名時(shí)可以為空。
      40. install 類型為DefaultTask,安裝任務(wù),可以為空。
      41. unstall 類型為DefaultTask,卸載任務(wù)。
      42. connectedAndroidTest 類型為DefaultTask,在連接設(shè)備上運(yùn)行Android測(cè)試的任務(wù)。
      43. providerAndroidTest 類型為DefaultTask,使用擴(kuò)展API運(yùn)行Android測(cè)試的任務(wù)。
        Android特定任務(wù)類型API:
      • ProcessManifest
        • 文件 manifestOutputFile
      • AidlCompile
        • 文件 sourceOutputDir
      • RenderscriptCompile
        • 文件 sourceOutputDir
        • 文件 resOutputDir
      • MergeResources
        • 文件 outputDir
      • MergeAssets
        • 文件 outputDir
      • ProcessAndroidResources
        • 文件 manifestFile
        • 文件 resDir
        • 文件 assetsDir
        • 文件 sourceOutputDir
        • 文件 textSymbolOutputDir
        • 文件 packageOutputFile
        • 文件 proguardOutputFile
      • GenerateBuildConfig
        • 文件 sourceOutputDir
      • Dex
        • 文件 outputFolder
      • PackageApplication
        • 文件 resourceFile
        • 文件 dexFile
      • File javaResourceDir
        • 文件 jniDir
        • 文件 outputFile
          • 在版本對(duì)象直接使用”outputFile”改變最終輸出文件
      • ZipAlign
        • 文件 inputFile
        • 文件 outputFile
          • 在版本對(duì)象直接使用”outputFile”改變最終輸出文件

      每一個(gè)任務(wù)類型的APK是有限的,這是由于Gradle的工作方式以及Android插件是如何建立的。
      首先,Gradle的任務(wù)僅僅配置了輸入輸出的位置以及可能的選項(xiàng)。因此,任務(wù)僅僅定義了輸入輸出。
      其次,大多數(shù)任務(wù)的輸入并不是無(wú)關(guān)緊要的,通常來(lái)自于資源集和構(gòu)建類型以及產(chǎn)品渠道的混合。為了保持構(gòu)建文件易于閱讀和理解,開發(fā)者通過(guò)領(lǐng)域特定語(yǔ)言對(duì)這些對(duì)象進(jìn)行微調(diào)就能夠進(jìn)行構(gòu)建,而不是深入改變項(xiàng)目的輸入和選項(xiàng)。
      另外也需要注意到的是,除了ZipAlign任務(wù)類型,所有的任務(wù)需要設(shè)置私有的數(shù)據(jù)才能工作。這意味著不可能手動(dòng)創(chuàng)建這些類型的新任務(wù)。
      主觀上API是能夠修改的。通常情況下當(dāng)前的API是圍繞著給定的輸入輸出(當(dāng)任務(wù)能夠添加額外必須的處理時(shí))。反饋是很重要的,特別是一些需求不可見時(shí)。
      關(guān)于Gradle的其他任務(wù)(DefaultTask, JavaCompile, Copy, Zip),請(qǐng)參考Gradle文檔。

      6.3設(shè)置Java語(yǔ)言等級(jí)

      你可以使用compileOptions代碼塊選擇編譯器的語(yǔ)言等級(jí),默認(rèn)情況下是基于compileSdkVersion的值。

      android {
          compileOptions {
              sourceCompatibility JavaVersion.VERSION_1_6
              targetCompatibility JavaVersion.VERSION_1_6
          }
      }
      

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多