Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 理解與配置android studio中的gradle

理解與配置android studio中的gradle

編輯:關於Android編程

使用gradle構建android應用時,你總是需要這樣一個文件:build.gradle。你應該已經看過這個文件了,如果沒有看過的話,你現在就可以看一下,它沒有多少內容。它的簡潔性得益於它提供了很多對設置和屬性的默認值。gradle是基於groovy語言的,但就使用它構建普通的工程的話,是可以不去學groovy的,如果想深入的做一下自定義的構建插件,可以考慮學一下groovy,因為它是基於java的,所以你有java基礎的話,學習不會很難。

這篇博客旨讓任何一個人能看懂android studio的gradle scripts,主要會從gradle的簡單語法,gradle scripts的腳本結構,每一個腳本(build.gradle,settings.gradle)的作用,腳本中每一項的意義等方面說明gradle scripts.

1.projects , tasks and action

是的,工程,任務和行為。一個項目至少要有一個工程,一個工程至少要有一個任務,一個任務由一些action組成。如果project比較抽象的話,可以這麼理解,一個build.gradle對應一個project,而action就好像java中的方法,他就是一段代碼的集合。在工程構建的過程中,gradle會根據build.gradle中的配置信息生成相應的project和task。

1.1構建過程

1.1.1初始化階段。根據build.gradle創建一個project實例。每一個project對應一個build.gradle腳本。也就是說這個過程會解析buile.gradle腳本,並使用它創建若干個project實例。

1.1.2配置階段。根據腳本配置委托對象。

1.1.3執行階段。執行tasks。

1.2 task

task標示一個邏輯上的執行單元,可以這樣聲明一個task:

 

task haha {
    println "haha"
}
然後使用gradle haha命令,就會打印出haha。這裡,haha這個任務被執行了,所以說task就是個執行單元。你還可以使用如下方法來定義task:

 

 

task hello << {
    println "hello world"
}
這和前者是有區別的,“<<”意思是給hello這個task添加一些action,其實就是調用了task的doLast方法,所以,它和以下代碼時等價的:

 

 

task hello {
    doLast{
        println "hello world"
    }
}
在android studio的頂層build.gradle中有這樣一個task:

 

 


task clean(type: Delete) { delete rootProject.buildDir }
可以看到這個task有一個類型type,task有很多種類型的,以下列出來一些:

\ 這裡用到了delete類型,task的類型可以這樣理解吧:task中文就是任務,任務有很多種類,Delete就是說這是個刪除文件的任務。

 

這裡就不更深入的探討task了,這些類容已經可以使我們可以理解android studio中遇到的內容了。

2.gradle DSL

DSL(Domain Specific Language),中文意思是特定領域的語言。gradle DSL就是gradle領域的語言。為了更好理解gradle,學習gradle DSL是有必要的。gradle的腳本雖然非常簡短,但它有它的語法,如果不搞懂DSL,即便你知道了怎麼修改腳本得到你想要的結果,你也不會理解為什麼要這樣修改。

2.1 你必須知道的基本概念

第一. gradle script是配置腳本,當腳本被執行的時候,它配置一個特定的對象。比如說,在android studio工程中,build.gradle被執行的時候,它會配置一個Project對象,settings.gradle被執行時,它配置一個Settings對象。Project,Settings這種對象就叫做委托對象,下圖展示了不同腳本對應的不同的委托對象:

\

第二.每一個Gradle script實現了一個Script接口,這意味著Script接口中定義的方法和屬性都可以在腳本中使用。

2.2構建腳本的結構

一個腳本由零個或多個statements和 script blocks組成。以下是對他們的說明,為了避免翻譯錯誤,這裡把原文貼出來。

A build script is made up of zero or more statements and script blocks. Statements can include method calls, property assignments, and local variable definitions. A script block is a method call which takes a closure as a parameter. The closure is treated as aconfiguration closurewhich configures some delegate object as it executes. The top level script blocks are listed below.

大概意思statments可以包括方法調用,屬性分配,本地變量定義;script bolck則是一個方法,它的參數可以是一個閉包。這個閉包是一個配置閉包,因為當它被執行的時候,它用來配置委托對象。以android studio的build.gradle為例:

 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.konka.gradletest"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
}

 

apply plugin: 'com.android.application'
以上就是一條statements,其中apply 是一個方法,後面是它的參數。

dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12'  compile 'com.android.support:appcompat-v7:23.3.0' }
以上是一個script block,它其實是一個方法(method),它的參數是一個閉包,閉包會被執行,用來配置它對應的委托對象。

 

gradle中有以下頂層script block:

\

這裡再以allprojects{ }為例,說一下script block是怎麼工作的:

 

allprojects {
    repositories {
        jcenter()
    }
}

 

allprojects{ }一般是頂層build.gradle中的一個script block,它就是一個方法,這個方法接受一個閉包作為參數。gradle工具會先創建一個Project對象,它是一個委托對象(delegate object),它創建以後,build.gradle被執行,執行的過程中,allproject{ }方法被調用,這個方法的參數是一個閉包,然後閉包會被執行,用來配置Project對象。

3.Understanding the Gradle files

理解了Project,task和action的概念以後,就可以就理解gradle的配置文件了。在android studio的工程中一般會有三個配置文件,它們各有各的功能。這三個文件的位置應該是這樣的:

\

3.1 settings.gradle

如果一個新的工程只包含一個android app,那麼settings.gradle應該是這樣的:

 

include ':app'
如果你的工程裡只有一個 app,那麼settings.gradle文件可以不要。include ':app'中的app指明你要構建的模塊名,android studio默認的模塊名師app,你可以把app目錄的名字改掉,比如改成hello,那麼這個時候你就必須把settings.gradle中的app也改成hello。這會是你非常有意義的一次嘗試,因為有了這次嘗試,以後你就可以按你所願修改這個文件了。比如就像這樣修改:

 

\


那麼這個時候你肯定已經想試試一次性構建多個app了吧?你以前如果做過,那麼你很厲害,你就不用看了,如果你沒有試過,那麼就和我一起試試吧:

第一步:在你的工程上右鍵,選擇新建mudole。

第二步:你成功了!

是的就這麼簡單,現在看看工程的樣子:

\

是的,這個時候,settings.gradle中多了一項,他就是我們新加的module的名字,它其實就是工程頂層目錄下的一個目錄的名字。這個名字你可以隨便改,module你也可以隨便加。

注意:settings.gradle實在初始化階段被讀入的,讀入以後會生成一個Settings對象,然後會調用這個對象的一些方法。你沒有必要了解這個對象,你知道它的存在對你理解項目構建的過程有所幫助。

3.2The top-level build file

就是頂層的build.gradle腳本。這個文件中配置內容將會應用到所有modules中(上一步我們已經創建了兩個module了,一個hello,一個gradletest2)。所以,每個module中都有的共同的屬性,都會在頂層的build.gradle中配置,它默認有以下內容:

 



buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }


 



這個腳本是由buildscript {},allprojects{} 兩個script block組成,buildsctipt是一個頂層的script block,正如2.2中所說的那樣,是一個方法,參數是一個閉包,這個閉包裡面又有一些script block,它們的本質都是一樣的。最終這些閉包會被執行,用來配置對應的委托對象。比如,repositories這個方法的閉包調用了jcenter方法,這個方法會配置gradle的遠程倉庫,配置好了以後,在工程構建過程中,如果缺少依賴,就會在遠程倉庫中查找。頂層build.gradle中的配置會應用到所有的工程中,頂層build.gradle的委托對象是root Project,子工程目錄下的build.gradle對應它自己的Project,總之,一個build.gradle對應一個Project。

 

到這裡,應該能看懂一個gradle script了,至於每個script block的意義,但從字面意思上就能猜出一些來,比如allprojects {}就是為所有的project配置閉包中的內容,這裡就是配置遠程倉庫,倉庫有很多種,想使用其他倉庫就可以在這裡修改。buildsctipt{}為所有project配置構建用的倉庫的工具,它裡面的dependecbies{}就是配置構建工具的信息,從中可以看到構建工具是gradle,版本是2.0.0;所以,修改gradle的版本就可以在這裡改。

3.3子工程下的build.gradle

 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.konka.gradletest"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
}
3.3.1第一行是一個statement,調用了apply方法,這個方法的定義如下:

 

 

void apply(Map options);
它的作用是檢查gradle有沒有所聲明的這個插件,有就什麼都不做,沒有的話就會使插件可用。

 

具體的每一個script block,它們都是方法,都可以在android studio 中按住ctrl+鼠標左鍵,點進去看它的聲明,每個方法都有注釋來解釋它的作用。

3.3.1 android block

android 是這個腳本中最大的塊,它包含了andoird特有的插件,這些插件可以使用是因為之前調用了

apply plugin: 'com.android.application',

此外,這裡設置了編譯android用的參數,構建類型等。

3.3.2 dependencies block

這裡設置了編譯當前的app的依賴。如果當前app依賴外部的包,可以把這個包放到libs目錄下面,然後右鍵,選擇add as library,

然後就會在這裡生成一條compile ' ... '的記錄。

3.3.3還有其他的一些配置,比如:

//這個是解決lint報錯的代碼 lintOptions { abortOnError false } //簽名設置 signingConfigs { myConfigs { storeFile file("簽名文件地址") keyAlias "..." keyPassword "..." storePassword "..." } } //混淆設置 buildTypes { release { signingConfig signingConfigs.myConfigs runProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } //渠道打包(不同包名) productFlavors { aaa{ applicationId = '包名' } bbb{ applicationId='包名' } } } //so文件的導入 task copyNativeLibs(type: Copy) { from fileTree(dir: 'libs', include: 'armeabi/*.so') into 'build/lib' }

總結:其實我覺得理解gradle的關鍵是理解script bolck與方法的對應關系,build.gradle等腳本與Project等對象的對應關系,以及理解Project和task的概念,這樣就基本對gradle有了很好地理解。然後再去研究每一個scripts block或者說是方法的作用,了解他們也很簡單,可以直接ctrl+鼠標左鍵點進去看這些方法的定義,看看他們的注釋就可以初步理解他們的功能了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved