天天看點

Android Gradle使用詳解(二) 之 項目結構和初識Java Gradle插件1 項目結構2 插件簡介3 Java插件

我們在上篇文章《Android Gradle使用詳解(一) 之 Gradle基礎》中介紹了一些關于Gradle的入門相關知識點。本文中會在此基礎上對Android工程中Gradle的相關知識進行進一步學習。

1 項目結構

我們在通過Android Studio建立一個APP工程時,目錄結構如下:

Android Gradle使用詳解(二) 之 項目結構和初識Java Gradle插件1 項目結構2 插件簡介3 Java插件

可以看到工程目錄中會自動生成一些檔案。其中可以看到一些我們熟悉的檔案,因為它們跟我們在上篇文章中的Hello World生成的是一樣的。有.gradle檔案夾、gradle檔案夾、build.gradle檔案、gradlew檔案、 gradlew.bat檔案 以及未見過的Settings檔案。我們現在就來一步步分析Android Studio建立工程後Gradld的相關知識點。

1.1 Settings檔案

在Gradle中,根目錄定義了一個設定檔案Settings,它是用于初始化以及工程樹的配置檔案。簡單說就是為了配置工程的子工程,在Android Studio中就是配置Project和Module。可以看到,我們在剛建立的APP工程New Project後Settings檔案隻是簡單的一行代碼:

include ':app'
           

若再執行New Model後,Settings檔案會自動變成這樣:

include ':app', ':mylibrary'
           

是以,一個子工程隻有在Settings檔案裡配置了Gradle才會識别,才會在建構的時候被包含進去。建立的Model預設是放在跟Project放在根目錄中,倘若需要更改存放位置于根目錄的sub-project檔案平下,也是很簡單,還是更改一下Settings檔案即可,例如:

include ':app', ':mylibrary'
project(':mylibrary').projectDir = new File('sub-project/mylibrary')
           

或者(此方式會在左邊Project面闆中多出一項sub-project的空的model)

include ':app'
include ':sub-project:mylibrary'
           

1.2 Build檔案

每個Project都會有一個Build檔案,它是Project建構的入口,正如上篇文章中的Hello World示例一樣。在Android Studio工程中,若存像上述中有app和mylibrary兩個子工程的話,則會出現3個Build檔案,它們分别是Root Project的build.gradle和兩個Child Project的build.gradle。其中Root Project的build.gradle檔案可以對Child Project統一配置,比如應用的插件、依賴的jcenter庫等。例如在Root Project的build.gradle檔案有這樣的配置代碼:

allprojects {
    repositories {
        google()
        jcenter()
    }
}
           

也有存在在Root Project的build.gradle中使用subprojects的情況。allprojects和subprojects的差別在于,allprojects是所有子產品配置,包括自己,而subprojects隻是對Child Project的配置。

2 插件簡介

Gradle本身内置了很多常用的插件像Java插件,Android Gradle插件就是基于内置的Java插件實作的。插件分二進制插件和腳本插件。使用插件前要先通過Project.apply()方法來應用它。

2.1 二進制插件

二進制插件就是實作了org.gradle.api.Plugin接口的插件,它們可以有plugin id,例如應用一個java插件:

apply plugin: 'java'
           

其中,’java’是Java插件的plugin id,它是唯一的。又例如應用android插件,可以看到Child Project的build.gradle檔案第一行是:

apply plugin: 'com.android.application'
           

2.2 應用腳本插件

應用腳本插件,其實就是把這個腳本加載進來,它使用的是關鍵字from,後面緊跟的是一個腳本檔案,可以是本地的,也可以是網絡的,如果是網絡上的話要使用HTTP URL。示例:

build.gradle

apply from:'version.gradle'

task hello << {
   println "APP version: ${versionName},code:${versionCode}"
}
           

version.gradle

ext {
   versionName = '1.0.0'
   versionCode = 100
}
           

示例中我們把APP的版本号和版本名稱單獨放在一個腳本檔案裡。這樣我們以後每次APP發版本隻需要更改version.gradle檔案即可。

2.3 第三方插件

若是第三方釋出的作為jar的二進制插件,我們在應用時,必須要先在buildscript{}裡配置其classpath才能使用。這個就好比Android Gradle插件,它是屬于第三方插件,它托管在Jcenter上,是以我們可以看到在Root Project的build.gradle檔案發現有這樣的配置代碼:

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

buildscript{}塊是一個在建構項目之前是,為項目進行前期準備和初始化相關配置依賴的地方,配置好所需的依賴後,就可以在Child Project的build.gradle中應用插件,如可見\app\build.gradle中的第一行代碼:

apply plugin: 'com.android.application'
           

3 Java插件

Android Gradle插件是基于内置的Java插件來實作的第三方插件,是以我們在開始學習Android Gradle插件前,先來了解Java插件。Java插件約定了項目結構,隻有我們遵循這些約定,Java插件才能找到我們的Java類、資源進行編譯、單元測試類等。預設情況下:

src/main/java                              源代碼存放目錄

src/main/resources                   打包資源檔案存放目錄

src/test/java                                單元測試用例存放目錄

src/test/resources                     單元測試中使用的檔案

3.1 約定的項目結構

main和test是Java插件内置的兩個源代碼集合,如果想自己添加一個如vip的目錄可以在build腳本裡這麼配置:

apply plugin: ‘java’
sourceSets {
	vip {

    }
}
           

添加一個vip的源代碼集合後,我們就可以在src下建立vip/java和vip/resurces目錄來存放vip相關的源代碼和資源檔案。當然預設的檔案目錄其實也可以修改的,例如:

sourceSets {
	vip {
	    java {
	       srcDirs ‘src/vip2/java’
        }
        resources.srcDirs = [‘src/ vip2/resources’]		// 另外一樣配置寫法
    }
}
           

如果要修改main和test兩個内置的兩個源代碼集合的存放目錄也是可以的,按照上面vip一樣,将其配置一下就可以。

除此之外,SourceSet裡的源集屬性有:

屬性名 類型 描述
name String 它是隻讀,比如main
output.classesDir File 該源集編譯後的class檔案目錄
output.resourcesDir File 編譯後生成的資源目錄
compileClasspath FileCollection 編譯後源集時所需的classpath
java SourceDirectorySet 該源集的Java源檔案
java.srcDirs Set 該源集的Java源檔案所在目錄
resources SourceDirectorySet 該源集的資源檔案
resources.srcDirs Set 該源集的資源檔案所在目錄

3.2 配置第三方依賴

我們在開發過程中,不可避免會依賴很多優秀的開源第三方Jar。要想使用這些第三方依賴,就要提前告訴給Gradle配置好如何找到這些依賴。例如上述提到Android Gradle是第三方插件,在使用前必須在repositories中進行配置,告訴Gradle是要去jcenter庫搜尋。

repositories

repositories {
    jcenter()
}
           

除jcenter庫以外,如若需要引用其它插件或Jar,我們也可以從mavenCentral、ivy、google或者自己搭建的Maven私服庫等中搜尋,例如:

repositories {
    jcenter()
	maven {
		url ‘http://www.xxx.com/’
	}
}
           

dependencies

配置好倉庫後,就可以繼續配置依賴了。還是例如上述提到Android Gradle是第三方插件,在repositories配置後就可使用dependencies來進行依賴配置:

dependencies {
    classpath 'com.android.tools.build:gradle:3.0.1'
    //classpath group: 'com.android.tools.build', name: 'gradle', version: '3.0.1'
}
           

除了classpath,還提供了以下的依賴配置:

implementation ( 原 compile)   編譯時依賴,依賴不可傳遞

api ( 原 compile)                       編譯時依賴,依賴可傳遞

compileOnly ( 原 provided)      編譯時依賴,但代碼不能打進包中

runtime                                      運作時依賴

testImplementation                    編譯測試用例時依賴,依賴不可傳遞

testApi                                       編譯測試用例時依賴,依賴可傳遞

testRuntime                               僅僅在測試用例運作時依賴

archives                                     項目釋出構件(JAR包等)依賴

default                                        預設依賴配置

3.3 依賴另一個Gradle項目

在項目内部中當Child Project裡的app要依賴另一個module時,一般就會在app的build.gradle檔案中加入以下的配置:

dependencies {
    compile project(':mylibrary')
}
           

如果依賴的是Jar包,則可以這樣:

dependencies {
    compile files( ‘libs/test.jar’, ‘libs/test2.jar’ )
}
           

或者可以依賴整個檔案夾下的所有Jar包:

dependencies {
    compile fileTree( dir  :  ‘libs’,  include  :  ‘*.jar’ )
}
           

在Android Studio 3.0開始推薦使用implementation取代了compile。它們的差別是implementation是依賴關系不可能傳遞,而compile可以。使用implementation可以降低項目依賴的偶合性和提高安全性。例如,項目中有app、module1、module2三個module,它們的依賴關系是這樣:app依賴module1,module1依賴module2,如果是使用compile依賴的話是可以做到依賴傳遞,但是如果使用implementation的話,依賴傳遞就會失效。

3.4 任務

Java插件為我們内置了很多有用的Task,下面列舉一些通用的任務:

任務名稱 類型 描述
compileJava JavaCompile 使用javac編譯Java源檔案
processResource Copy 把資源檔案拷貝到生成的資源檔案目錄裡
classes Task 組裝産生的類和資源檔案目錄
compileTestJava JavaCompile 使用javac編譯Java源檔案
processTestResources Copy 把測試資源檔案複制到生産的資源檔案目錄裡
testClasses Task 組裝産生的測試類和相關資源檔案目錄
jar Jar 組裝Jar檔案
Javadoc Javadoc 使用javadoc生成Java API文檔
test Test 使用Junit或TestNG運作單元測試
uploadArchives Upload 上傳包含Jar的建構,用archives{}閉包配置
clean Delete 清理建構生成的目錄檔案
cleanTaskName Delete 删除指寫任務生成的檔案,比如cleanJar删除Jar任務生成的

我們在使用Android Studio建立工程後,便能在Root Project的build.gradle中的最後看到clean任務的配置:

task clean(type: Delete) {
    delete rootProject.buildDir
}
           

對于内置的main和test源集 或者 自己新增的源集(像上面示例的vip)也有一些源集任務:

任務名稱 類型 描述
compileXXJava JavaCompile 使用javac編譯指寫源集的Java源代碼
processXXResources Copy 把指寫源集的資源檔案複制到生産檔案下的資源目錄中
XXClasses Task 組裝給指寫源集的類和資源檔案目錄

3.5 屬性

Java插件為我們也内置了很多有用的屬性,這些屬性都被添加到Project中,可以直接使用,比如前面提到的sourceSets,下面列舉一些常用的源集屬性:

屬性名 類型 描述
sourceSets SourceSetContainer 該Java項目的源集,可以通路和配置源集
sourceCompatibility JavaVersion 編譯Java源檔案使用的Java版本
targetCompatibility JavaVersion 編譯生成的類的Java版本
archivesBasenName String 打包成Jar或Zip檔案的名字
manifest Manifest 用于通路或配置manifest清單檔案
libsDir File 存放生成的類庫目錄
distsDir File 存放生成的釋出的檔案的目錄

繼續閱讀