1. 程式人生 > >Android Studio Gradle檔案解釋其作用

Android Studio Gradle檔案解釋其作用

新手在使用AndroidStudio時通常會遇到如下問題: 
1. Android sutdio開啟一個工程一直卡在Background Tasks怎麼辦? 
2. 手動配置Gradle Home後,怎麼還是提示錯誤? 
3. 下載了Gradle,配置了gradle home,為什麼開啟工程顯示還要在遠端庫下載?

為了能全面,徹底滴解決上述問題,先了解下gradle到底是什麼?Studio中用她做了些什麼?

Gradle是一種構建指令碼,用Groovy語言實現,一種類似於java的語言。AndroidStudio使用Gradle作為構建工具,是構建工具就必須管理依賴庫,當工程中使用了開源庫時只需在build.gradle中告知gradle從哪個遠端庫下載就可以了。下面詳細介紹AndroidStudio工程的settings.gradle、Project的build.gradle、Module的build.gradle、gradle/wrapper這些檔案分別是用來幹什麼的。

Project的settings.gradle

include ':app'
1
2
位於工程的根目錄,用於指示 Gradle 在構建應用時應將哪些模組包括在內 
當然一個工程可以包含多個moudle,若還有一個lib moudle ,settings.gradle則如下:

include ':app', ':lib'
1
Project的build.gradle

位於工程的跟目錄,指定Gradle構建所引用的倉庫和依賴的外掛

/**
* buildscript 配置gradle的依賴,此處不能配置模組的依賴
**/
buildscript {
    /**
    * repositories 告知gradle從哪裡下載自身的依賴庫,
    * 目前支援JCenter, Maven Central, and Ivy,也可以配置自己使用的依賴庫
    **/
    repositories {
       jcenter()
    }
    /**
    * 配置gradle構建工程的依賴外掛(Android Plugin for Gradle)的版本
    **/
    dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.8.3'
    }
}

/**
* 配置工程中所有模組的遠端依賴倉庫。若工程某個模組中不依賴這裡定義的遠端倉庫,則需在模組的build.gradle中申明
**/
allprojects {
    repositories {
        jcenter()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Module的build.gradle

模組級 build.gradle 檔案位於每個 // 目錄,用於配置適用於其所在模組的構建設定。您可以通過配置這些構建設定來提供自定義打包選項(例如附加構建型別和產品風味),以及替換 main/ 應用清單或頂級 build.gradle 檔案中的設定。

/**
* 應用com.android.application外掛構建此模組
**/

apply plugin: 'com.android.application'

/**
 *開始配置安卓特定的編譯選項
 */

android {

  /**
   * compileSdkVersion 指定gradle構建時採用的API版本,應用可以在當前版本的系統或者比當前版本更低的系統中執行
   * buildToolsVersion 指定編譯工具的版本,可以通過SDK Manager下載相應的版本
   */

  compileSdkVersion 25
  buildToolsVersion "25.0.0"

  /**
   * defaultConfig 封裝預設設定和編譯變數,能根據編譯系統動態得重寫AndroidManifest.xml中的屬性
   */

  defaultConfig {

    /**
     * applicationId 應用的名字
     * 但是程式碼中的包名仍然參考main/AndroidManifest.xml
     */

    applicationId 'com.example.myapp'

    // 定義執行的最小系統版本
    minSdkVersion 15

    // 執行執行的api版本,通常和compileSdkVersion一致
    targetSdkVersion 25

    // 定義應用的版本
    versionCode 1

    // 定義對使用者的版本
    versionName "1.0"
  }

  /**
   * buildTypes 配置了許多的編譯型別。預設情況下,定義了debug 和release兩種。
   * debug編譯型別在編譯系統中預設支援,不用配置。編譯時採用debugging tools而簽名採用debug key
   * release 編譯型別應用了混淆設定,但是在預設情況下沒有簽名。
   */

  buildTypes {

    /**
     * 預設情況下,Android Studio 對release編譯型別進行了配置,
     * minifyEnabled減少應用的體積,並且指定了混淆設定檔案
     */

    release {
        minifyEnabled true // Enables code shrinking for the release build type.
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }

  /**
   * productFlavors 字面翻譯是產品口味,在多渠道打包用的比較多,或者是針對同一款應用不同的使用限制。
   * 在productFlavors中可以重寫defaultConfig中的配置。在預設情況下編譯系統是沒有建立productFlavors的。
   * 這裡示範建立了付費和免費兩種產品特性,每種特性定義了不同的應用id,所以同一款手機可以同時安裝者款應用
   */

  productFlavors {
    free {
      applicationId 'com.example.myapp.free'
    }

    paid {
      applicationId 'com.example.myapp.paid'
    }
  }

  /**
   * 拆分專用版本的apk,以減小應用的提交
   * 比如:jni時分別拆分成arm版和x86版
   *       或者根據螢幕密度拆分
   *
   */

  splits {
    // Screen density split settings
    density {

      // Enable or disable the density split mechanism
      enable false

      // Exclude these densities from splits
      exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
    }
  }
}

/**
 * 本模組的依賴配置
 */

dependencies {
    compile project(":lib")
    compile 'com.android.support:appcompat-v7:25.1.0'
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
Gradle 屬性檔案

Gradle 還包括兩個屬性檔案,位於專案根目錄,可用於指定適用於 Gradle 構建工具包本身的設定:

gradle-wrapper.properties

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
1
2
3
4
5
6
位於工程的gradle\wrapper目錄,用於配置gradle,若IED將工程的gradle配置成Use default gradle wrapper 模式,當GRADE_HOME(預設為C:\Users\Administrator.gradle)中沒有工程指定的gradle版本,則主動從網上下載。 
下載這部分的邏輯實現在gradle\wrapper\gradle-wrapper.jar中可以通過反編譯檢視其原始碼,GradleWrapperMain.java中先讀取gradle-wrapper.properties配置的版本資訊,若預設目錄不存在對應的Gradle,則從配置的網站上下載。

local.properties

ndk.dir=E\:\\Tools\\ADT\\ndk-bundle
sdk.dir=E\:\\Tools\\ADT
1
2
3
為構建系統配置本地環境屬性,例如 SDK 安裝路徑。由於該檔案的內容由 Android Studio 自動生成並且專用於本地開發者環境。

Android Studio IDE Gardle 配置

如上圖所示:

Project-level settings

Use default gradle wrapper(recommended): 是否讓gradle-wrapper.jar根據gradle-wrapper.properties的定義去查詢對應的gradle。優先本地查詢,若本地不存在則再在gradle-wrapper.properties中定義的distributionUrl地址中下載。下載的Gradle會存放在

<Service directory path>/wrapper/dists/Gradle-xxxxx/然後是奇怪的一竄/gradle-xxxxx.zip
1
下載完成後會自動解壓。

Use local gradle distribution: 
選擇之後Gradle home才可以設定,為本工程指定本地存在的Gradle,為了減少麻煩需要最好使用gradle-wrapper.properties中定義的版本,否則有可能存在同步不通過的情況

Globle Gradle Setting

Offline work: 
跟下面的Service directory path 不存在關聯。選擇表示在Service directory path目錄中已經下載好了各種依賴庫,不用gradle再去下載。如果選擇了,但是所在目錄中卻沒有依賴庫,則會提示如下錯誤:

Error:No cached version of com.google.guava:guava:18.0 available for offline mode.
<a href="toggle.offline.mode">Disable Gradle 'offline mode' and sync project</a>
1
2
如下圖所示:

點選下 Disable Gradle offline mode and sync project ,Android Studio 會自動反選此項,並下載所依賴的庫,下載的庫會儲存在

<Service directory path>/caches 目錄
1
Service directory path: 
此前我一直以為此項和上面的Offline work是存在關聯的,只能說我太天真,囧~~。 
和上面的Offline work是獨立的,用來設定下載gradle 和依賴庫的存放路徑。

問題解答

有了上面的詳細介紹,剛開始提的三個問題是不是很容易解答了呢?

問題1.

卡頓是由於要下載Gradle。按如下方式解決:

本地存有工程使用的Gradle

可以直接在Use local gradle distribution中指定gradle 路徑點選確定稍等片刻即可: 


本地沒有Gradle

在專案gradle設定中選擇Use default gradle wrapper,studio會自動下載相應的gradle版本到 service directory path 目錄。 

由於網路原因,通常花費時間較長,直接強制從工作管理員關閉Studio
手動從網路上下載gradle/wrapper/gradle-wrapper.properties中定義的gradle版本。先將/wrapper/dists/Gradle-xxxxx/然後是奇怪的一竄/ 目錄中的零時檔案刪除,再將下載的壓縮包拷貝過來。
再重新啟動Studio,gradle解壓後,會自動從遠端依賴庫中下載所需要的依賴庫
問題2

那是因為選擇了 Offline work 模式導致。gradle只是構建工具,若依賴的第三方庫不存在則會提示出錯。 
不選擇Offline work ,gradle構建工具會自動從遠端依賴庫中下載所需要的各種庫。

問題3

只是配置了gradle,gradle只是構建工具。第三方依賴的庫就是通過gradle從遠端依賴庫中下載的,若下載庫時間長,應該是本地網速不好導致。 
 
顯示類似上圖的下載是很正常的,表示構建工具正在從遠端依賴庫中下載依賴檔案!

其他問題

Error:Failed to complete Gradle execution. 
Cause: 
檔名、目錄名或卷標語法不正確。 
Gradle 目錄配置不正確導致