Gradle for Android簡要指南

前言 Android官網構建系統介紹https://developer.android.com/studio/build/index.html

Gradle 是 Android 現在主流的編譯工具,雖然在Gradle 出現之前和之後都有對應更快的編譯工具出現,但是 Gradle 的優勢就在於它是親兒子,Gradle 編譯比較慢,這和它的編譯過程有關,但是最近伴隨着 Android Studio2.0的發佈(目前官網最新gradle 爲2.2.0), Gradle 也進行了一次非常大的升級,叫Instant Run.它的編譯速度網上有人用逆天兩個字來形容。(雖然目前有 Bug 我們要相信,他會好的) 對於一些比較複雜的,特別是多人團隊合作的項目我們會需要一些個性化的配置來提高我們的開發效率。一些高級功能需要我們手動的去配置gradle腳本。 按官網流程一一介紹,有疏漏的請留言,我們一起學習 首先來張大圖

Paste_Image.png

對於一個典型的Android應用程序模塊構建過程,遵循以下一般步驟:

1. 編譯器轉換你的源代碼轉換成DEX(Dalvik的可執行文件)的文件,其中包括Android設備上運行的字節碼,和其他一切編譯資源。

2. 該APK包裝結合了DEX文件,資源編譯成一個單一的APK。之前可以安裝你的應用程序並部署到Android設備,但是,APK必須簽名。

3. 該APK打包簽署使用Debug或發佈密鑰庫您的APK: a. 如果您正在構建您的應用程序,這是一個調試版本,應用程序你打算僅用於測試和分析後,打包簽署您的應用程序與調試密鑰庫。Android Studio中自動配置與調試密鑰庫的新項目。 b. 如果您正在構建您的應用程序,你要在外部釋放的發行版中,打包簽署您的應用程序一起發佈密鑰庫。要創建一個發佈密鑰庫,瞭解Android Studio中籤署您的應用程序。

4. 產生最終的APK之前,打包使用zipalign工具來優化您的應用程序在設備上運行時,使用較少的內存。

在構建過程的最後,您有一張調試APK或釋放您的應用程序,你可以用它來部署,測試或釋放到外部用戶的APK。

以上是官網對apk打包過程的一個簡要概括,我們根據官網對gradle進行一個簡單的介紹:

1. Build Types 定義了編譯類型,針對每個類型我們可以有不同的編譯配置,不同的編譯配置對應的有不同的編譯命令。默認的有debug、release 的類型。

buildTypes {
   release {
       minifyEnabled true
       proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
   }

   debug {
       applicationIdSuffix ".debug"
   }

2. Product Flavors 如果我們需要針對同一份源碼編譯不同的程序(包名也不同),比如 免費版和收費版。我們就需要Product flavors。 注意,Product flavorsBuild Type是不一樣的,而且他們的屬性也不一樣。所有的 product flavor 版本和defaultConfig 共享所有屬性! 像Build type 一樣,product flavor 也可以有自己的source set 文件夾。除此之外,product flavor 和 build type 可以結合,他們的文件夾裏面的文件優先級甚至高於 單獨的built type 和product flavor 文件夾的優先級。如果你想對於 blue類型的release 版本有不同的圖標,我們可以建立一個文件夾叫blueRelease ,注意,這個順序不能錯,一定是 flavor+buildType 的形式。

productFlavors {
     demo {
         applicationId "com.example.myapp.demo"
         versionName "1.0-demo"
     }
     full {
         applicationId "com.example.myapp.full"
         versionName "1.0-full"
     }
 }

3. Build Variants 在開發中我們可能會有這樣的需求: -- 我們需要在debug 和 release 兩種情況下配置不同的服務器地址; -- 當打市場渠道包的時候,我們可能需要打免費版、收費版,或者內部版、外部版的程序。 -- 渠道首發包通常需要要求在歡迎頁添加渠道的logo。等等 -- 爲了讓市場版和debug版同時存在與一個手機,我們需要編譯的時候自動給debug版本不一樣的包名。 這些需求都需要在編譯的時候動態根據當前的編譯類型輸出不同樣式的apk文件。這時候就是我們的buildType大展身手的時候了。

4. Manifest Entries 您可以在構建變量的配置清單文件的一些屬性的值。這些構建值清單文件覆蓋現有值。如果您想爲您的模塊,其中每個APK文件有不同的應用程序名稱,最小的SDK版本,或目標SDK版本多個APK這是非常有用的。

defaultConfig {/**
 * applicationId uniquely identifies the package for publishing.
 * However, your source code should still reference the package name
 * defined by the package attribute in the main/AndroidManifest.xml file.
 */applicationId 'com.example.myapp'// Defines the minimum API level required to run the app.minSdkVersion 14// Specifies the API level used to test the app.targetSdkVersion 23// Defines the version number of your app.versionCode 1// Defines a user-friendly version name for your app.versionName "1.0"}

5. Dependencies 構建系統管理從本地文件系統,並從遠程倉庫項目的依賴。這可以使您不必手動搜索,下載和你的依賴的二進制包拷貝到你的項目目錄 。這裏提供下marven倉庫的搜索地址:http://search.maven.org/ 不用翻牆也可以的哦

android {...}
...
dependencies { // The 'compile' configuration tells Gradle to add the dependency to the
 // compilation classpath and include it in the final package.

 // Dependency on the "mylibrary" module from this project
 compile project(":mylibrary") // Remote binary dependency
 compile 'com.android.support:appcompat-v7:23.4.0'

 // Local binary dependency
 compile fileTree(dir: 'libs', include: ['*.jar'])
}

6. Signing 如果我們打包市場版的時候,我們需要輸入我們的keystore數據。如果是debug 版本,系統默認會幫我們配置這些信息,祕鑰在home/.android/debug.keystore。這些信息在gradle 中都配置在signingConfigs中。

android {
 signingConfigs {
     config {
         keyAlias keystoreProperties['keyAlias']
         keyPassword keystoreProperties['keyPassword']
         storeFile file(keystoreProperties['storeFile'])
         storePassword keystoreProperties['storePassword']
     }
 } ...}

7. ProGuard 構建系統使您可以指定每個構建變量不同ProGuard的規則文件。構建系統可以運行ProGuard的構建過程中縮小和模糊處理的類。說白了,就是在gradle中進行混淆配置

android {
 buildTypes {     release {
         minifyEnabled true
         proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
                 'proguard-rules.pro'
     }
 }
 ...
}

Note: Android Studio disables ProGuard when using Instant Run.

8. APK Splits 構建系統可以自動建立不同的APK,每個只包含代碼,需要一個特定的屏幕密度或應用程序二進制接口(ABI)的資源。

android {
...
splits { // Configures screen density split settings
 density {   // Enables density APK splits
   enable true

   // Specifies a list of screen densities Gradle should not create APK splits for
   exclude "ldpi", "xxhdpi", "xxxhdpi"

   // Specifies a list of compatible screen size settings for the manifest
   compatibleScreens 'small', 'normal', 'large', 'xlarge'
 }
}
}

當啓動一個新的項目,Android的Studio會自動創建一些這些文件對你來說,並填充它們基於合理的默認值。

Paste_Image.png

1. The Gradle Settings File

2. The Top-level Build File

3. The Module-level Build File

4. Gradle Properties Files 目錄結構及gradle詳細說明官網都說的很清晰 https://developer.android.com/studio/build/index.html#build-files, 掌握了以上的基本結構和基本寫法,簡單的Android工程構建基本上不會有什麼問題了 有gradle語法不瞭解的童鞋可直接查看官網代碼 https://docs.gradle.org/current/userguide/userguide.html 很龐大知識體系,接下來我們稍微瞭解一些與Android相關的gradle進階應用

Gradle腳本不是像傳統的xml文件那樣,而是一種基於Groovy的動態DSL,而Groovy語言是一種基於jvm的動態語言。

Project和tasks 在grade中的兩大重要的概念,分別是project和tasks。每一次構建都是有至少一個project來完成,所以Android studio中的project和Gradle中的project不是一個概念。每個project有至少一個tasks。每一個build.grade文件代表着一個project。tasks在build.gradle中定義。當初始化構建進程,gradle會基於build文件,集合所有的project和tasks,一個tasks包含了一系列動作,然後它們將會按照順序執行,一個動作就是一段被執行的代碼,很像Java中的方法。 構建的生命週期 一旦一個tasks被執行,那麼它不會再次執行了,不包含依賴的Tasks總是優先執行,一次構建將會經歷下列三個階段:

Paste_Image.png

生命週期事件可以在指定的生命週期之前、之中或者之後發生,在執行階段之後發生的生命週期事件就該是構建的完成了。假設你希望在構建失敗時能夠在開發階段儘早得到反饋,給構建生命週期事件添加回調有兩種方法:一是通過閉包,二是實現Gradle API的一個監聽接口,Gradle並沒有要求你監聽生命週期事件,這完全決定於你,通過監聽器實現的優勢就是可以給你的類寫單元測試,看看下面這幅圖會有一點直觀的印象:

Paste_Image.png

在配置階段,Gradle決定在任務在執行階段的執行順序,依賴關係的內部結構是通過直接的無環圖(DAG)來表示的,圖中的每一個任務稱爲一個節點,每一個節點通過邊來連接,你很有可能通過dependsOn或者隱式的依賴推導來創建依賴關係。記住DAG圖從來不會有環,就是說一個已經執行的任務不會再次執行,下面這幅圖將要的展示了這個過程:

項目結構 和eclipse對比來看,Android studio構建的結構有很大的不同:

 MyApp
   ├── build.gradle
   ├── settings.gradle
   └── app
       ├── build.gradle
       ├── build
       ├── libs
       └── src
           └── main
               ├── java
               │   └── com.package.myapp
               └── res
                   ├── drawable
                   ├── layout
                   └── etc.

gradle使用了一個叫做source set的概念,官方解釋:一個source set就是一系列資源文件,其將會被編譯和執行。對於Android項目,main就是一個source set,其包含了所有的資源代碼。當你開始編寫測試用例的時候,你一般會把代碼放在一個單獨的source set,叫做androidTest,這個文件夾只包含測試。(此處不做測試開發可以不用瞭解) 使用Gradle Wrappe防止新版本迭代所導致的問題 grade只是一個構建工具,而新版本總是在更迭,所以使用Gradle Wrapper將會是一個好的選擇去避免由於gradle版本更新導致的問題。Gradle Wrapper提供了一個windows的batch文件和其他系統的shell文件,當你使用這些腳本的時候,當前gradle版本將會被下載,並且會被自動用在項目的構建,所以每個開發者在構建自己app的時候只需要使用Wrapper。所以開發者不需要爲你的電腦安裝任何gradle版本,在mac上你只需要運行gradlew,而在windows上你只需要運行gradlew.bat。 在目錄指定gradle插件版本

dependencies { classpath 'com.android.tools.build:gradle:1.2.3' }

,在項目的gradle/wrapper目錄下面有個gradle-wrapper.properties中有如下內容:

distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

修改URL也可以對gralde插件版本的控制。

關於gradle具體用法,我們後續再更新,gradle用法太雜,我們慢慢梳理 ?


Android歷練記 是一個關於Android最新技術探討,包含安全,架構,Android技術開發,ui繪製,源碼解析等領域,如果你有興趣,我們可以一起討論學習, 關注微信公衆號 Android歷練記 或掃一掃二維碼:

Android歷練記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章