1. 程式人生 > >gradle入門 (指南介紹)

gradle入門 (指南介紹)

Gradle是一門基於groovy的DSL(特定領域語言)語言,也就是說它只能在某一特定領域使用,而不通用。
學習Gradle主要需要掌握下面三種語言
1 、Groovy語言
2 、Gradle DSL
3 、Android DSL
我們前面說了Gradle是一門基於groovy的DSL,可能很多童鞋會對這個有迷惑,第一感覺就是Gradle是一門獨立的語言呀,如果你這麼想就“誤入歧途“了,因為我一開始也是這麼迷糊的,當你瞭解過後,你就可以這麼理解Gradle就是用groovy語言實現的一個框架,我們基於這個框架可以方便的去寫構建指令碼。
由於Android Studio已經採用並內嵌了Gradle作為構建指令碼,所以我們簡單的看下AS中的Gradle結構。
我們在AS中新建一個專案都會有這個目錄
這裡寫圖片描述


這個是什麼呢?這個就是所謂的Gradle包裝器了,這個4.1 呢就是Gradle的版本號,你想想框架也需要不斷升級增加或者廢棄掉一些功能呀,所以這個版本號越新表示表示Gradle的語法越新。
這個版本號我們怎麼控制呢?
這裡寫圖片描述
開啟gradle-wrapper.properties就可以在箭頭處去指定修改Gradle版本號
這裡寫圖片描述

我們也可以在在File選項中進行配置
這裡寫圖片描述

這裡寫圖片描述

在Android Studio中整個專案結構是一個Project,裡面的android應用以及library目錄都是module,Project結構下主要如下:

.gitignore檔案 :這個是git的忽略配置檔案
build.gradle : 這個是整個工程的gradle指令碼配置,這裡面指令碼內容會在所有的module上生效
gradle.properties : 這個檔案可以配置jvm虛擬機器一些引數,也可以調整設定記憶體大小。
local.properties :這個檔案是配置sdk、ndk目錄路徑的,這個路徑根據個人主機環境變數自動生成,所以我們需要把它新增到gitgore忽略檔案中。
settings.gradle :這裡面配置我們整個工程所有需要依賴到的module,包括android應用以及依賴到的library

AS首先執行Project的build.gradle指令碼進行構建,這個指令碼中所有的配置對所有module生效,接著會去執行setting.gradle指令碼,首先去執行apply plugin: ‘com.android.application’ 應用目錄下的build.gradle指令碼進行構建,接著依次執行其他module下的build.gradle指令碼,這就是AS主要工作流程。

我們開啟Project下的build.gradle看下結構內容
這裡寫圖片描述

這些都是Gradle DSL語法進行配置,dependencies 下面依賴的就是Android Gradle外掛,這裡我們必須新增,這個版本號跟上面Gradle版本號有相互對應關係,因為外掛是基於Gradle版本寫的,太高的Gradle版本對應太低的Gradle版本亦或相反都不支援,這裡貼張官網的圖看下就明白了。

到此為止,我們對Android Studio中的gradle指令碼結構差不多瞭解了,接下來我們瞭解下gradle語法

每個build.gradle指令碼就是一個Project,一個專案工程由若干個Project構建而成,而一個Project又是由若干個Task組成,每個Task又會執行若干個Action, 執行setting.gradle指令碼時,會為裡面每個目錄下的build.gradle建立一個Project例項。

這裡寫圖片描述

上圖我們配置dependencies dsl實際就是呼叫Project物件的方法. 而Android標籤下的dsl屬於Android DSL,Android DSL提供特定配置Android Studio專案工程的一些api,它不屬於Gradle Api。
Gradle DSL Api可以查閱文件:
https://docs.gradle.org/current/dsl/org.gradle.api.Project.html

我們前面說了一個Project是由若干個Task組成,每個 Task 都代表了構建執行過程中的一個原子性操作(如編譯,打包,生成 javadoc,釋出到某個倉庫等操作),我們隨便開啟一個專案工程看下task究竟是什麼
這裡寫圖片描述

可以看到,build目錄下存放的是我們構建時需要在我們在執行gradlew build命令時,會依次按順序執行build下面的Task,我們也可以配置自己的Task.由於沒有安裝工具,這麼就直接在gradle指令碼檔案中測試。

這裡寫圖片描述

Task申明語法是 task xxx { }
這裡我申明瞭一個名稱為task1的task,我建立了一個Map,Map中只有一個簡單的鍵值對,然後在task1中遍歷這個Map然後分別打印出key和value值,程式碼就是這麼簡單我們執行build命令看下結果。

這裡寫圖片描述

可以清楚的看到已經打印出了key value值,如果你熱愛思考的話你可能會疑問為什麼執行build命令時會執行我們的task列印結果,我們明明沒有執行task1呀。
這就需要了解gradle的2個生命週期 配置階段 、執行階段

1 .配置階段

上面task1中程式碼就屬於配置階段,在Project執行任何task任務前會執行這個Project中所有配置程式碼。我們上面執行build命令實際就是執行一堆task進行構建,構建前會執行配置程式碼

2. 執行階段

執行階段的程式碼就是一個個的Action,doLast是Gradle提供的Api, 舉個例子上面同樣程式碼配置到執行階段可以這樣寫
這裡寫圖片描述
我們將配置階段程式碼包裹在doLast中這樣就會將程式碼從配置階段轉換為執行階段了,我們再執行下build命令試一下
這裡寫圖片描述
結果可以看到只執行列印了配置階段的程式碼,而我們放在執行階段裡的Map並沒有被列印,現在我們執行這個task1在看下結果
這裡寫圖片描述

這裡為了測試我在task1上面的android標籤里加了段配置程式碼所以從列印結果可以看到,我們執行task之前會先依次執行所有task裡的配置,然後才去執行我們task裡的Action

我們點選doLast原始碼看看
這裡寫圖片描述

可以看到實際就是把我們{ }整個閉包作為引數傳遞給doLast引數,然後轉化成一個Action物件存入ArrayList集合,所以我們執行task實際就是獲取到這個集合並遍歷然後呼叫每個Action執行execute(T t)方法最終會呼叫閉包Closure的call()方法。

在application app的build.gradle中,我們會發現有這麼一句程式碼

apply plugin: 'com.android.application'  

我們前面說了這段程式碼的意思是應用安卓外掛申明這個build.gradle所屬的專案是android應用,如果要想申明為依賴庫的話就要應用library外掛

apply plugin: 'com.android.library'  

當然我們也可以去應用自己寫的外掛,gradle提供給我們Plugin介面用於擴充套件自己的外掛,方式很簡單隻要編寫xxx.grovvy檔案實現Plugin介面就好,例如:

class ApkPlugin implements Plugin<Project>{
    @Override
    void apply(Project target) {
         target.task("test1")<<{
             println "test1"
         }
    }
}

我們這裡建立了一個ApkPlugin外掛,程式碼也很簡單,Plugin介面中有個apply方法必須實現,Plugin介面有個泛型,這個泛型就是我們外掛所應用的指令碼型別,它會作為一個物件傳遞到apply方法中,比如我們在build.gradle指令碼中應用我們的外掛,build.gradle整體就是一個Project物件,所以我們這裡泛型就申明為Project.

當我們在build.gradle中增加apply plugin: ApkPlugin應用我們寫的外掛後,整個build.gradle會作為一個Project引數傳遞給apply方法,上面程式碼很簡單,就是呼叫Project的task(String taskName)引數方法去建立一個task並應用到Project物件中,然後我們在命令中執行下這個task看下結果

這裡寫圖片描述
可以看到我們已經成功為這個project添加了task並執行成功。

我們在build.gradle中經常可以看到大量這樣的語句
這裡寫圖片描述
圓圈處是我們對Android工程進行一些常規的屬性配置,可能看到這你會很迷糊,我知道要這樣寫,可是為什麼非要這樣寫呢,這裡需要了解Extension(擴充套件),因為在gradle指令碼中,這種思想被大量運用。

我們這麼想,如果官方提供的外掛不滿足我們需求,那麼我們需要編寫自己的外掛,上面為了測試方便直接把外掛寫到了build.gradle腳本當中,但實際上我們最好不要這麼幹,因為程式碼需要複用,如果我把外掛做成依賴提供給別人使用的話,那麼我們在外掛內部程式碼中怎麼獲取到外部配置的值呢?

我們還以上面編寫的ApkPlugin為例。

這裡寫圖片描述
但是你會發現這裡程式碼稍微有些變動,在外掛裡建立task之前呼叫了這麼一句

 project.getExtensions().create("ApkDistExtension",ApkDistExtension)

getExtensions()方法點進去可以看到得到的是一個ExtensionContainer物件。
這裡寫圖片描述

這裡寫圖片描述
看文件介紹這個介面允許將DSL擴充套件名稱空間新增到一個指定物件中,這個介面可以建立我們指定需要擴充套件配置的型別物件,並且給這個物件設定一個額外的名稱空間,然後將建立的物件賦值為呼叫這個介面方法物件的成員變數中。

在上面例子中我們建立了一個ApkDistExtension類,裡面有個versionName String型別的成員變數,初始值是null,在建立task之前,我們呼叫ExtensionContainer物件的create方法建立了一個ApkDistExtension物件並且給這個物件名稱空間設定為“ApkDistExtension”,這裡也可以任起其他命名,然後把建立的這個物件賦值成project物件裡的一個成員變數。

然後在build.gradle中我們可以通過我們設定的名稱空間進行配置

ApkDistExtension{
  versionName "v1.0.1"
}

在apply方法中就可以這樣獲取到我們配置的值

project["ApkDistExtension"].versionName

這裡寫圖片描述
執行task1可以列印獲取到我們配置的值,看到這你應該就明白上面android專案為什麼要那麼配置了。

在國內有眾多應用市場,我們如果針對不通市場打包不同應用分別投放的話,gradle給我提供了productFlavors這個便捷的DSL.
我們可以把公共的引數配置放在預設配置 defaultConfig{ }中,然後在android標籤內利用productFlavors進行特有的風味配置 例如:
這裡寫圖片描述

這裡寫圖片描述

這裡我分別配置了3個版本 HuaWei、XiaoMi、MeiZu,當然你也可以配置更多版本,這裡面每個版本都會與defaultConfig進行合併如果有重複的配置,productFlavors中版本的配置會覆蓋掉defaultConfig中的配置,productFlavors中每個版本會跟defaultConfig合併然後分別跟buildTypes中每個版本合併生成一個最終版本的apk,比如上面例子中合併規則會這樣
HuaWei配置->(合併)defaultConfig 配置->(合併)buildTypes release配置
HuaWei配置->(合併)defaultConfig 配置->(合併)buildTypes debug配置

XiaoMi配置->(合併)defaultConfig 配置->(合併)buildTypes release配置
XiaoMi配置->(合併)defaultConfig 配置->(合併)buildTypes debug配置

MeiZu配置->(合併)defaultConfig 配置->(合併)buildTypes release配置
MeiZu配置->(合併)defaultConfig 配置->(合併)buildTypes debug配置

如果我們需要統計渠道的話我們可以在AndroidManifest.xml檔案下的application標籤內新增一個meta-data

<meta-data android:name="CHANNEL_VALUE"   
         android:value="${channel_value}"/>

這裡value我們不寫死,用個變數代替
這裡寫圖片描述
這裡我們又使用了一個android外掛提供的 manifestPlaceholders DSL
productFlavors中這麼配置之後,我們打包apk時就可以把不同版本配置中channel_value的值替換到AndroidManifest哪個變數裡

然後在啟動Activity中我們就可以這樣寫獲取到不同版本的渠道值

    public static String getAppMetaData(Context ctx, String key) {
        if (ctx == null || TextUtils.isEmpty(key)) {
            return null;
        }
        String resultData = null;
        try {
            PackageManager packageManager = ctx.getPackageManager();
            if (packageManager != null) {
                ApplicationInfo applicationInfo = packageManager.getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA);
                if (applicationInfo != null) {
                    if (applicationInfo.metaData != null) {
                        resultData = applicationInfo.metaData.getString(key);
                    }
                }

            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return resultData;
    }

封裝這麼個方法後直接呼叫getAppMetaData(this,”CHANNEL_VALUE”)就可以獲取到我們不同渠道的值了,
我們看下不同版本列印的渠道值
HuaWei:
這裡寫圖片描述

MeiZu:
這裡寫圖片描述

XiaoMi:
這裡寫圖片描述

可以看到打印出的分別是不同版本獲取到的渠道,是不是美滋滋~

applicationVariants

這個是android外掛給我們提供的一個屬性,它有什麼作用呢?
我們前面說過,利用productFlavors可以設定多個不同的版本,這些版本還會跟defaultConfig以及buildTypes組成多個不同的版本,這些不同的版本就是Build Variants(構建變體),如果我們想利用程式碼動態的去控制改變這些構建變體資訊的話就可以利用這個屬性。

這裡寫圖片描述

比如上面我建立了2個風格版本,我們想打包的時候,打包輸出apk名字首對應版本名怎麼辦呢?利用applicationVariants很容易實現我們看程式碼
這裡寫圖片描述

程式碼很簡單,這裡遍歷整個Project的構建變體,記住這裡要用all去遍歷否則不生效,然後遍歷每個構建變體的所有outputs輸出,然後把每個構建變體版本名賦值給每個構建變體輸出File,這樣打包後就會輸出不同版本名的apk

注意由於Android外掛3.0後更改,修改輸出檔名不要用下面這種寫法了否則會編譯報錯
這裡寫圖片描述

這裡寫圖片描述

相關推薦

gradle入門 (指南介紹)

Gradle是一門基於groovy的DSL(特定領域語言)語言,也就是說它只能在某一特定領域使用,而不通用。 學習Gradle主要需要掌握下面三種語言 1 、Groovy語言 2 、Gradle DSL 3 、Android DSL 我們前面說了

Java Gradle入門指南之依賴管理(新增依賴、倉庫、版本衝突)

    開發任何軟體,如何管理依賴是一道繞不過去的坎,軟體開發過程中,我們往往會使用這樣那樣的第三方庫,這個時候,一個好的依賴管理就顯得尤為重要了。作為一個自動構建工作,Gradle對依賴管理有著很好的支援。     通常我們使用IDE(Eclipse、IDEA、Android Studio)開發Java

Gradle入門指南(二)

轉載請標明出處: 本文出自:【ouyida3的部落格】 注意:本文內容都是通過gradle命令列完成,不涉及eclipse的外掛。 1、先閱讀 2、常用命令 gradle -v gradle build gradle build --

Java Gradle入門指南之內建與定製任務類

1.內建任務類(in-built tasks) Gradle在不斷地更新,其內建任務也在不斷地豐富,這一章節介紹Gradle中最常用的幾個內建任務類,這只是Gradle眾多內建任務類中的一部分,拋磚引玉,更多方法可以參見Gradle官方文件 1.1 複

Asp.Net MVC4入門指南(1): 入門介紹

前言 本教程將為您講解使用微軟的Visual Studio Express 2012或Visual Web Developer 2010 Express Service Pack 1 來建立一個ASP.NET MVC4 Web應用程式所需要的基礎知識。建議您使用Visual Studio 2012,你將不再

OpenStack雲端計算入門指南——Nova元件介紹

Open Stack Compute Infrastructure (Nova) Nova是OpenStack雲中的計算組織控制器。支援OpenStack雲中例項(instances)生命週期的所有活動都由Nova處理。這樣使得Nova成為一個負責管理計算資源、網路、認

Redis入門指南-筆記-進階

back 進階 返回 單位 告訴 watch 是把 場景 如果 4.1 事務 (1) 事務是一組命令的集合 (2) 事務同命令一樣是Redis的最小執行單位,一個事務中的命令要麽都執行,要麽都不執行。 (3) 格式:

機器學習入門 - 1. 介紹與決策樹(decision tree)

recursion machine learning programmming 機器學習(Machine Learning) 介紹與決策樹(Decision Tree)機器學習入門系列 是 個人學習過程中的一些記錄與心得。其主要以要點形式呈現,簡潔明了。1.什麽是機器學習?一個比較概括的理解是:

【翻譯Autofac的幫助文檔】1.入門指南

tran 忘記 ref face 設計 一個表 uil 國際 article 【寫在前面】嘗試做完一件工作之外自我覺得有意義的一件事,那就從翻譯Autofac的幫助文檔吧。 入門指南 將Autofac集成你的應用程序的步驟通常很簡單,一般是: 時刻以IOC(控制反

easyui 入門指南

param 功能 eight 移動 支持 定義 padding 入門指南 cti 所有easyui組件都有,屬性,方法,事件,用戶可以簡單的對其擴展. 屬性 屬性定義在 jQuery.fn.{plugin}.defaults中.例如, 對話框組件[dialog]的屬性定

(官網)虛幻3--入門指南: 遊戲性元素

要點 生命周期 頁面 bsp 定時 ade 定義 根據 基礎 入門指南: 遊戲性元素 入門指南: 遊戲性元素 概述 遊戲類型概述 玩家概述 HUD和UI概述 概述 有幾個遊戲性元素實際上是所有使用虛幻引擎3或虛幻開發工具包創建的項目所共有的。自定義

人工智能、機器學習和認知計算入門指南

不遠 要素 人工 算法 網絡拓撲 界面 分布 target 用戶 幾千年來,人們就已經有了思考如何構建智能機器的想法。從那時開始,人工智能 (AI) 經歷了起起落落,這證明了它的成功以及還未實現的潛能。如今,隨時都能聽到應用機器學習算法來解決新問題的新聞。從癌癥檢測和預測到

實力幹貨,一名成功VR設計師的入門指南

AR VR 從2016年開始,虛擬現實技術進入了爆發性增長時期!隨著硬件設備的不斷更叠,VR技術已經廣泛應用於娛樂遊戲、購物、影視媒體、醫療健康、科研教學、房地產、旅遊行業等領域!然而硬件的發展依然缺少VR內容的支持,因此VR設計師的吃香程度不言而喻。 據最新的薪資數據

Maven入門指南(二)

deploy ... web服務器 快速 repos 必須 轉載 關於 net 轉載自並發編程網 – ifeve.com本文鏈接地址: Maven入門指南(二) Maven目錄結構 Maven有一個標準的目錄結構。如果你在項目中遵循Maven的目錄結構,就無需在pom文件中

WEEX入門指南

download img 通路 文件內容 jpg 編輯器 data 入口 ins 背景 由於公司項目需要,需求變化頻繁,計劃總改不上變化,由於app更新版本周期長,不能很好應對這種變化,正在此前提下熱修復和熱更新技術也有了發展的空間,不管熱修復還是熱更新,都是對app內容或

Android 音視頻開發入門指南

入門 精通 提高 android 音視頻 最近收到很多網友通過郵件或者留言說想學習音視頻開發,該如何入門,我今天專門寫篇文章統一回復下吧。 音視頻這塊,目前的確沒有比較系統的教程或者書籍,網上的博客文章也都是比較零散的,希望我後面能擠出時間整一個專題詳細講一講~~目前的話,我

Android Gradle Plugin指南(三)——依賴關系、android庫和多項目配置

tool 全部 ocs 共享 項目路徑 多項目配置 path 用戶 so文件 原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Dependencies-Android-L

webpack入門指南-step03

示例 針對 ports 鏈接 輕量 在哪裏 文件中 機制 瀏覽器緩存 一、webpack 的使用 webpack簡單點來說就就是一個配置文件,所有的魔力都是在這一個文件中發生的。 這個配置文件主要分為三大塊 entry 入口文件 讓webpack用哪個文件作為項目的入口

webpack入門指南-step04

可選 nor gin 查看 world 你會 是把 all uil 一、建立項目 建一個文件夾,然後新建一個package.json的文件在項目根目錄下 如果你使用git管理你的這個項目的話,建議你新建一個.gitignore文件,不要讓git提交一些node依賴的模塊,

MariaDB快速入門指南

mariadb 數據庫 linux 快速入門目錄 前言 一、數據庫中的數據結構 與SQL語言 1、數據結構 2 、SQL語言 二、MariaDB安裝及初始化配置 1、安裝 2、配置防火墻