Gradle基礎(chǔ)

最近需要做了一個功能泳赋,需要將Android工程中的一個lib庫中所依賴的aar诽俯、jar等直接都打包,在最后的生成產(chǎn)物中-aar包含以上所有的依賴庫呛占;我們在開發(fā)Android過程中虑乖,也會遇到對編譯過程進行干擾;當前Android工程的開發(fā)都是基于Gradle進行構(gòu)建的晾虑,等等這些都要求對于Gradle我們需要進行一個比較全面的了解疹味。

什么是Gradle

Gradle是一個開源的構(gòu)建腳本工具,能夠協(xié)助大家更好的提高開發(fā)效率帜篇;Gradle的構(gòu)建腳本都是使用Groovy或者Kotlin或者Java編寫的糙捺;Gradle提供了大量的API,我們可以根據(jù)這些API編寫出自己的工具(Plugin-插件工具)笙隙,利用自己編寫的工具實現(xiàn)自己的需求洪灯,例如:復制文件、將特定文件目錄的java源代碼打包成jar包等竟痰。Gradle構(gòu)建工具在最后還是啟動了JVM签钩,幫助自己干事情掏呼。

Gradle初體驗

對于Gradle的安裝可以參考官方文檔,安裝完成以后我們可以使用 gradle init(對于IDE創(chuàng)建工程边臼,這個命令有IDE自己完成)命令初始化一個gradle構(gòu)建的工程哄尔,查看當前的文件目錄如下:

├── build.gradle
├── settings.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat

這個就是使用gradle構(gòu)建一個工程必須的一些文件,這些文件的和我們創(chuàng)建的Android工程是不是有點類似呢柠并。接下來對這些文件的用途做一個簡單的介紹:
build.gradle:主要是為執(zhí)行的一些task配置一些參數(shù)岭接,或者在這里添加自己的參數(shù)等;對應與Android構(gòu)建工程中臼予,在該文件中配置了編譯時使用的sdk版本鸣戴、編譯工具版本等參數(shù);這里配置中最終要的一點就是需要使用哪些插件粘拾,使用了什么插件就是使用了哪些task窄锅;
setting.gradle:配置一下當前工程目錄中,哪些子工程需要參與構(gòu)建缰雇;
gralde:該目錄中包含了gradle-wrapper.jar和gradle-wrapper.properties兩個文件入偷,其中jar包就是一個可執(zhí)行的gradle,gradle-wrapper.properties主要是配置一些與這個可執(zhí)行jar包相關(guān)的參數(shù):

#Sun Mar 11 21:54:32 CST 2018
#分配的最基本的地址路徑械哟,主要是用于存儲gradle.jar
distributionBase=GRADLE_USER_HOME 
#gradle.jar存儲的相對路徑疏之,與前面的基本路徑組合成了絕對路徑
distributionPath=wrapper/dists    
#下載gradle.jar的zip類型文件存儲的基本路徑
zipStoreBase=GRADLE_USER_HOME     
#zip文件存儲的相對路徑,與前面的基本路徑組合為絕對路徑
zipStorePath=wrapper/dists        
#需要下載的對應版本gradl壓縮包
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip  

gradlew與gradlew.bat:這兩個文件都是可執(zhí)行的腳本暇咆,功能都是相同的锋爪,只是對應不同系統(tǒng)下的執(zhí)行腳本,分別對應Unix base和Window系統(tǒng)爸业。執(zhí)行該腳本的功能與直接在命令行執(zhí)行g(shù)radle功能是相同的其骄,那這個腳本存在的意義是什么呢,主要的意義在于可以執(zhí)行特定版本的gradle扯旷,也就是上面gradle文件下的jar包拯爽,我們需要修改gradle-wrapper.properties下對應的屬性,并重新執(zhí)行g(shù)radlew腳本就會重新下載钧忽。

Gradle與插件

對于插件比較直觀的體驗就是安裝了插件我可以使用特定的功能某抓,例如在瀏覽器上安裝了Octotree,我們在瀏覽Github上的開源工程的時候惰瓜,可以在左側(cè)直接查看工程目錄。對于Gradle構(gòu)建的工程汉矿,如果我們需要使用某些特定功能的構(gòu)建工具崎坊,也是以插件的形式完成的。

插件的主要功能就是利用Gradle 定義的API實現(xiàn)自己的功能洲拇,前面已經(jīng)說過Gradle開放了大量的API奈揍,這些API主要是定義了基本的一些功能:copy文件曲尸、文件打包為jar包等;對于Android開發(fā)來說比較常見的插件有下面兩個:

//構(gòu)建Android App的插件
apply plugin: 'com.android.application'
//構(gòu)建Android Lib的插件
apply plugin: 'com.android.library'

其實上面的這些插件都是Android官方為廣大開發(fā)者提供的男翰,對于App構(gòu)建的過程有了解過的人肯定比較清晰的知道另患,里面包括了R.java文件的生成、dex文件的生成蛾绎、打包等昆箕;對于正常情況下如果不使用自動打包構(gòu)建腳本,我們肯定需要使用Android提供的最原生的工具aapt租冠、dx等按部就班的生成對應的文件和轉(zhuǎn)換鹏倘,最后打包壓縮為APK文件。但是使用這些構(gòu)建腳本可以大大提高我們的開發(fā)效率顽爹、發(fā)布效率纤泵、構(gòu)建效率等。

自定義Gradle插件-自己動手

在構(gòu)建自己的Gradle之前需要了解兩個基本的API接口镜粤,方便更好的理解自己編寫的Gradle插件捏题。

基本知識點

Project

在前面初步體驗Gradle的時候,簡單的創(chuàng)建了一個Gradle構(gòu)建工程肉渴,對于一個工程就對應與Gradle中的一個Project對象公荧,Project對象里面定義了大量與該工程對應的變量、操作方法等黄虱。我們在使用 gradle 工具構(gòu)建工程的時候會讀取目錄文件中的 build.gradle 文件稚矿,該文件配置了Project相關(guān)的屬性;

Task

對于一個工程來說捻浦,當需要構(gòu)建的時候肯定需要一步一步的完成某些步驟晤揣,最后產(chǎn)生自己需要的產(chǎn)物;對于Gradle構(gòu)建來說朱灿,把這些一個一個的步驟對應了一個Task對象昧识;還是以Android打包過程來進行分析,如果我們需要將當前的java原文件編譯成class文件盗扒,這里就需要使用cmpileJava這個Task跪楞;對于Android打包的插件也就是定義了大量的Task,然后將這些Task添加到Project中侣灶,并定義好它們的順序甸祭,在構(gòu)建腳本啟動的時候按照先前定義好的順序,逐個執(zhí)行這些Task褥影,最終就會得到我們自己想要的產(chǎn)物—APK文件池户。

開始自定義

下面就開始來編寫自己的插件,并執(zhí)行運行該插件。首先需要創(chuàng)建一個Gradle構(gòu)建工程校焦,直接使用 gradle init 命令創(chuàng)建了我們在第一部分的工程目錄:

├── build.gradle
├── settings.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat

然后使用如下命令創(chuàng)建目錄:

mkdir -p buildSrc/src/main/java/com/github/songnick/example

然后創(chuàng)建文件:buildSrc/src/main/java/com/github/songnick/example/ExamplePlugin.java

package com.github.songnick.example;

import org.gradle.api.Plugin;
import org.gradle.api.Project;

public class ExamplePlugin implements Plugin<Project> {
    @Override
    public void apply(Project project) {
        project.getTasks().create("hello", HelloTask.class, (task) -> { 
            task.setMessage("Hello");
            task.setRecipient("World");                                
        });
    }
}

這里是實現(xiàn)了插件接口赊抖,并重寫了apply方法,在該方法中使用project對象提供的接口定義了一個Task—HelloTask寨典,這里的project對象就是上面的部分介紹到的氛雪,可以通過這個project對象獲取工程構(gòu)建的文件目錄、依賴的庫等信息耸成。對于HelloTask類的具體定義如下:

buildSrc/src/main/java/com/github/songnick/example/HelloTask.java

package com.github.songnick.example;

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

public class HelloTask extends DefaultTask {
    private String message;
    private String recipient;

    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }

    public String getRecipient() { return recipient; }
    public void setRecipient(String recipient) { this.recipient = recipient; }

    //具體的任務執(zhí)行注解
    @TaskAction
    void sayGreeting() {
        System.out.printf("%s, %s!\n", getMessage(), getRecipient()); 
    }
}

這里的@TaskAction注解表示最后調(diào)用這個任務的執(zhí)行方法报亩;
當我們創(chuàng)建和編寫完成上面的文件以后,當前的文件目錄結(jié)構(gòu)就變?yōu)榱耍?/p>

├── build.gradle
├── buildSrc
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── github
│                       └── songnick
│                           └── example
│                               ├── ExamplePlugin.java
│                               └── HelloTask.java
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

多出了buildSrc文件目錄及里面的文件墓猎,這個時候直接執(zhí)行 gradle命令或者./gradlew 這個時候就會編譯buildSrc文件下的java文件捆昏,并生成了編譯過后相關(guān)的產(chǎn)物,可以通過buildSrc/build/文件目錄去查看對應的產(chǎn)物毙沾,其中包括class文件骗卜、jar包等。這里有可能比較疑惑左胞,為什么執(zhí)行這個命令會編譯buildSrc文件下對應的文件寇仓,這個是gradle工具在執(zhí)行構(gòu)建的時候默認會把當前文件目錄下的buildSrc文件作為自己的默認編譯目錄。現(xiàn)在我們編譯完成了烤宙,怎么驗證我們編寫的插件是否能夠正常使用呢遍烦,用編輯器打開當前目錄中的build.gradle文件,并添加如下字段:

apply plugin: com.github.songnick.example.ExamplePlugin

然后執(zhí)行 ./gradlew tasks 結(jié)果中會看到:

Other tasks-----------hello

這里就是我們通過自定義的插件添加的Task-名字叫hello躺枕;我們可以直接執(zhí)行該task:./gradlew hello 查看結(jié)果服猪。

上面是通過自己在命令行純手工實現(xiàn)了一個自定義的插件以及Task,當然也可以通過其他IDE創(chuàng)建插件工程拐云,并實現(xiàn)發(fā)布等罢猪,這些對應的教程也比較多,這里就不詳細介紹叉瘩。主要是希望通過上面簡單的創(chuàng)建過程大家可以直接的感受一下自定義插件膳帕。

構(gòu)建Gradle插件-編程語言

上面自定義插件的部分中,我們使用了Java語言編寫了相關(guān)接口的實現(xiàn)薇缅、類的繼承等危彩;其實對于插件的編寫Gradle構(gòu)建工具還支持Groovy,對于語言來說我們不需要糾結(jié)太多泳桦,每個語言都有其特點汤徽;那么Gradle為啥要支持除了Java語言的Groovy語言呢,我個人的理解其實很簡單灸撰,可以從Android工程使用Gradle構(gòu)建看出谒府,我們需要對工程做一些配置漆羔,這些配置都是放在 build.gradle 中,我們發(fā)現(xiàn)在配置這些參數(shù)的時候就是使用了Groovy語言的特性狱掂。對于Groovy語言是DSL(領(lǐng)域?qū)S谜Z言),這些語言的設(shè)計初衷是給非程序員使用亲轨,所以設(shè)計的時候就會更加的容易讓人理解趋惨,使用起來更方便;對于Grooy語言的學習大家可以自行學習惦蚊,這里就不過多的介紹了器虾。

后記

簡單的把Gradle的基礎(chǔ)的基本概念和自己的理解闡述 了一下,更多的學習資料還是直接訪問官網(wǎng)吧蹦锋,對于插件的編寫以及Groovy的學習可以直接學習Android構(gòu)建插件的源碼吧兆沙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市莉掂,隨后出現(xiàn)的幾起案子葛圃,更是在濱河造成了極大的恐慌,老刑警劉巖憎妙,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件库正,死亡現(xiàn)場離奇詭異,居然都是意外死亡厘唾,警方通過查閱死者的電腦和手機褥符,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抚垃,“玉大人喷楣,你說我怎么就攤上這事『资鳎” “怎么了铣焊?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長魂迄。 經(jīng)常有香客問我粗截,道長,這世上最難降的妖魔是什么捣炬? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任熊昌,我火速辦了婚禮,結(jié)果婚禮上湿酸,老公的妹妹穿的比我還像新娘婿屹。我一直安慰自己,他們只是感情好推溃,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布昂利。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜂奸。 梳的紋絲不亂的頭發(fā)上犁苏,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音扩所,去河邊找鬼围详。 笑死,一個胖子當著我的面吹牛祖屏,可吹牛的內(nèi)容都是我干的助赞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼袁勺,長吁一口氣:“原來是場噩夢啊……” “哼雹食!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起期丰,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤群叶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咐汞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盖呼,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年化撕,在試婚紗的時候發(fā)現(xiàn)自己被綠了几晤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡植阴,死狀恐怖蟹瘾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掠手,我是刑警寧澤憾朴,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站喷鸽,受9級特大地震影響众雷,放射性物質(zhì)發(fā)生泄漏脐湾。R本人自食惡果不足惜玫鸟,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一谅将、第九天 我趴在偏房一處隱蔽的房頂上張望垂攘。 院中可真熱鬧,春花似錦沼死、人聲如沸也搓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狠鸳。三九已至揣苏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間件舵,已是汗流浹背卸察。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铅祸,地道東北人蛾派。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像个少,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子眯杏,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,099評論 25 707
  • 什么是 Gradle 夜焦? 所謂構(gòu)建工具就是對你的項目進行編譯、運行岂贩、簽名茫经、打包、依賴管理等一系列功能的合集萎津,傳統(tǒng)的...
    方子晗閱讀 500評論 0 0
  • Gradle是基與Groovy的腳本配置的構(gòu)筑工具,用與構(gòu)筑Java及Android應用. Gradle Grad...
    花京院典明閱讀 1,156評論 0 8
  • 突然又說到小時候卸伞, 想當年我是多愛說話, 想當年數(shù)學多簡單锉屈, 想當年同學是多單純荤傲, 想當年總喜歡表現(xiàn), 想當年想哭...
    怎么都被用了呢閱讀 218評論 2 5
  • 追求美是一種人的本能颈渊,雖然每個人心目中的美不盡相同遂黍,追求美的方式也千奇百怪。黑夜為燈提供了綻放異彩的土壤俊嗽,...
    霸王東渡閱讀 224評論 1 3