寫給Android開發的Gradle知識體系

2021-02-13 劉望舒
前言

老讀者都知道,我的技術博客從2016年開始就沒寫過不成系列的文章,這些系列文章組成了目前Android領域最全面深入的原創知識體系,更恐怖的是這個體系還在不斷的成長,關於這個知識體系可以點擊 閱讀原文 了解。

今天我給大家帶來的是Android Gradle系列文章的開篇,實際上在Android Gradle系列之前,我已經寫了Gradle核心思想系列,這個系列我儘量避免了Gradle和Android之間的關聯,這是因為在了解Gradle的核心思想後,可以更好的理解Android Gradle,因此這裡強烈建議先閱讀Gradle核心思想系列。

為什麼現在要用Gradle?

Gradle入門前奏

Groovy快速入門看這篇就夠了

看似無用,實則重要的Gradle Wrapper

通俗易懂的Gradle插件講解

通俗易懂的自定義Gradle插件講解

1.什麼是Gradle的Android插件

在通俗易懂的Gradle插件講解這篇文章中我們知道,Gradle有很多插件,為了支持Android項目的構建,谷歌為Gradle編寫了Android插件,新的Android構建系統就是由Gradle的Android插件組成的,Gradle是一個高級構建工具包,它管理依賴項並允許開發者自定義構建邏輯。Android Studio使用Gradle wrapper來集成Gradle的Android插件。需要注意的是,Gradle的Android插件也可以獨立於AndroidStudio運行。
在 Android的官方網站提到了新的Android構建系統主要有以下幾個特點:

Gradle的Android插件結合Android Studio成為了目前最為流行的Android構建系統。

2. Android Studio的模塊類型和項目視圖

Android Studio中的每個項目包含一個或多個含有原始碼文件和資源文件的模塊,這些模塊可以獨立構建、測試或調試,一個Android Studio的模塊類型可以有以下幾種:

Android應用程式模塊
 Android應用程式模塊可能依賴於庫模塊,儘管許多Android應用程式只包含一個應用程式模塊,構建系統會將其生成一個APK。

Android 庫模塊
Android庫模塊包含可重用的特定於Android的代碼和資源,構建系統會將其生成一個AAR。

App 引擎模塊
包含應用程式引擎集成的代碼和資源。

Java 庫模塊
包含可重用的代碼,構建系統會將其生成一個JAR包。

Android Studio3.3.2 中的Android項目視圖如下所示。

1.png
所有構建文件在 Gradle Scripts 層級下顯示,大概介紹下這些文件的用處。

項目build.gradle:配置項目的整體屬性,比如指定使用的代碼倉庫、依賴的Gradle插件版本等等。

模塊build.gradle:配置當前Module的編譯參數。

gradle-wrapper.properites:配置Gradle Wrapper,可以查看Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper這篇文章。

gradle.properties:配置Gradle的編譯參數。具體配置見Gradle官方文檔

settings.gradle:配置Gradle的多項目管理。

local.properties:一般用來存放該Android項目的私有屬性配置,比如Android項目的SDK路徑。

這篇文章主要介紹項目build.gradle和模塊build.gradle。

3.項目build.gradle

我們新建一個Android項目,它的項目build.gradle的內容如下:

buildscript {
    repositories {
        google()
        jcenter()   
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2' 
    }
}

allprojects {
    repositories {
        google()
        jcenter()  
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

注釋1處配置依賴的Gradle插件版本,Gradle插件屬於第三方插件,因此這裡在buildscrip塊中配置谷歌的Maven庫和JCenter庫,這樣Gradle系統才能找到對應的Gradle插件。
如果使用google()報not found: 'google()'錯誤,可以用如下代碼替代:

maven { url 'https://maven.google.com' }

如果你還不理解Gradle插件,可以查看Gradle核心思想(五)通俗易懂的Gradle插件講解這篇文章。

4.模塊build.gradle

新建一個Android項目,它的模塊build.gradle的內容如下:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

4.1 Gradle的Android插件類型

apply引入的插件id為com.android.application,說明當前模塊是一個應用程式模塊,Gradle的Android插件有多個類型分別為:

應用程式插件,插件id為com.android.application,會生成一個APK。

庫插件,插件id為com.android.library,會生成一個AAR,提供給其他應用程式模塊用。

測試插件,插件id為com.android.test,用於測試其他的模塊。

feature插件,插件id為com.android.feature,創建Android Instant App時需要用到的插件。

Instant App插件,插件id為com.android.instantapp,是Android Instant App的入口。

4.2 Android塊

Android塊用於描述該Module構建過程中所用到的所有參數。

4.2.1 defaultConfig塊

Android塊中的defaultConfig塊用於默認配置,常用的配置如下所示。


buildTypes塊用於配置構建不同類型的APK。4.2.2 buildTypes塊

當我們新建一個項目時,在Android塊已經默認配置了 buildTypes塊:

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

在AS的Terminal中執行gradlew.bat build命令,會在該模塊的build/outputs/apk目錄中生成release和debug的APK,雖然只配置了release ,但release和debug是默認配置,即使我們不配置也會生成。也可以修改默認的release和debug,甚至可以自定義構建類型,比如:

 buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug {
            debuggable true
        }
        privitedebug{
            applicationIdSuffix ""
        }
    }

這時會在build/outputs/apk目錄中生成release、debug、privitedebug的APK。
buildTypes塊還可以配置很多屬性,常用的配置如下所示。

4.2.3 signingConfigs塊

用於配置籤名設置,一般用來配置release模式。

signingConfigs {
        release {
            storeFile file('C:/Users/liuwangshu/.android/release.keystore')
            storePassword 'android'
            keyAlias 'androidreleasekey'
            keyPassword 'android'

        }

4.2.4 其他配置塊

android塊中除了前面講的defaultConfig塊、buildTypes塊、signingConfigs塊還有其他的配置塊,這裡列舉一些。

更多的配置塊請參考官方文檔。

4.2.4 全局配置

如果有多個module的配置是一樣的,可以將這些配置提取出來,也就是使用全局配置。全局配置有多種方式,這裡介紹其中的兩種。
1. 使用ext塊配置
 在項目build.gradle中使用ext塊,如下所示。

ext{
    compileSdkVersion =28
    buildToolsVersion ="28.0.3"
    minSdkVersion =15
    targetSdkVersion =28
}

在某個module的build.gradle中使用配置:

apply plugin: 'com.android.application'
android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    defaultConfig {
        applicationId "com.example.liuwangshu.hookinstrumentation"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
  ...
}
...

2. 使用config.gradle配置
首先在根目錄下創建config.gradle文件來進行配置。
config.gradle

ext{
    android=[
            applicationId:"com.example.liuwangshu.hookinstrumentation",
            compileSdkVersion :28,
            buildToolsVersion :"28.0.3",
            minSdkVersion : 15,
            targetSdkVersion : 28,
    ]

    dependencies =[
            "appcompat-v7" : "com.android.support:appcompat-v7:28.0.0",
            "constraint"  : "com.android.support.constraint:constraint-layout:1.1.3",
    ]
}

接著在項目build.gradle中添加apply from: "config.gradle",這樣項目的所有module都能用config.gradle中定義的參數。
最後在module的build.gradle中使用配置:

apply plugin: 'com.android.application'
android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion
    defaultConfig {
        applicationId rootProject.ext.android.applicationId
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
   ...
dependencies {
    implementation rootProject.ext.dependencies["constraint"]
    implementation rootProject.ext.dependencies["appcompat-v7"]
    ...
}

4.2 dependencies 塊

dependencies 塊用於配置該module構建過程中所依賴的所有庫。Gradle插件3.4版本新增了 api 和 implementation 來代替 compile 配置依賴,其中 api 和此前的 compile是一樣的。dependencies和api主要以下的區別:

感謝
https://jeroenmols.com/blog/2017/06/14/androidstudio3/
http://google.github.io/android-gradle-dsl/current/
http://www.androiddocs.com/tools/building/plugin-for-gradle.html
https://www.jianshu.com/p/8962d6ba936e
https://www.jianshu.com/p/b6744e1e4f7c
《Android群英傳 神兵利器》

相關焦點

  • 掌控 Android Gradle
    對本文有任何問題,可加我的個人微信:kymjs123Gradle 裡的幾乎任何東西都是基於這兩個基礎概念:掌握了這兩個,你就掌握了一大半的 Gradle 知識了。首先講 Task字面理解為任務,Gradle 中所有執行的事件都是藉由 Task 執行的。
  • 原創 | 看完此文,你對Gradle的理解又升級了!
    作者:劉望舒http://liuwangshu.cn/application/android-gradle/2-gradle-dependency.htmlGradle知識體系為什麼現在要用Gradle?
  • 擁抱Android Studio(二):Android Studio與Gradle深入
    CSDN移動將持續為您優選移動開發的精華內容,共同探討移動開發的技術熱點話題,涵蓋移動應用、開發工具、移動遊戲及引擎、智能硬體、
  • 給 Android 開發者的 Gradle 入門指南
    #掃描二維碼報名源創會#原文:Beginner’s Guide to Gradle for Android Developers連結:https://journals.apptivitylab.com/beginners-guide-to-gradle-for-android-developers
  • Gradle 與 Android 構建入門
    . # 打包成 apk6. zip xxx.apk [需要打包的代碼和資源]在 Android 中代碼對資源是通過 R.java 文件引用,於是需要繼續添加命令,並要求這個命令在 javac 命令前執行。在
  • 【實戰】Android工程gradle詳解
    這時我們就需要對所有的版本進行統一的管理,管理的方式有兩種:rootProject我們可以把一些需要用的欄位都放在project的build.gradle(注意是project的不是module的)中:這樣,在module的build.gradle中可以進行讀取:
  • 這一次,徹底了解 Gradle 吧!
    必須注意:每一個 Gradle 版本都會對應一個 Daemon 進程,機器內若是運行過多個版本的 Gradle,那麼機器內就會存在多個 Daemon 進程,AS 開發 android 項目,我推薦使用 Gradle 本地文件,不依靠每個 android 項目中 wrapper 管理 gradle 版本,具體後面會說明。
  • 經驗丨Android開發最佳實踐
    gradle.properties文件。+'compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.如果那樣的話,你需要使用Gardle和adb命令行。如果使用Eclipse集成Gradle 不適合你,你只是使用命令行構建工程,或遷移到Android Studio中來吧。無論你使用何種開發工具,只要確保Gradle和新的項目結構保持官方的方式構建應用程式,避免你的編輯器配置文件加入到版本控制。例如,避免加入Ant build.xml文件。
  • [乾貨] 【譯】Android 開發規範與應用
    │  └─ proguard-rules.pro├─ build.gradle└─ settings.gradle主要的區別在於,新的結構明確的分開了'source sets' (main,androidTest),Gradle的一個理念。
  • 翻譯自國外大牛總結的各種Android開發經驗和實用技巧
    切換到 gradle 3.3執行下面的代碼升級你的 gradle wrapper./gradlew wrapper --gradle-version 3.3 --distribution-type all全局 gradle.properties 如下設置android.enableBuildCache=true停止 gradle 構建進程    .
  • 這一次,徹底了解 Gradle 吧!
    必須注意:每一個 Gradle 版本都會對應一個 Daemon 進程,機器內若是運行過多個版本的 Gradle,那麼機器內就會存在多個 Daemon 進程,AS 開發 android 項目,我推薦使用 Gradle 本地文件,不依靠每個 android 項目中 wrapper 管理 gradle 版本,具體後面會說明。
  • 谷歌Android Studio 和 Gradle 插件使用全新版本編號
    因此,即使在開發周期的後期,您也可以安全地更新 Android Studio 版本,因為您的項目 AGP 版本與 Android Studio 版本可以採用不同的節奏進行更新。最後,在新的版本系統中,只要您的 AGP 版本保持在穩定版,您或您的團隊就可以在應用項目中更加方便地同時運行穩定版和預覽版 Android Studio。
  • 谷歌:Android Studio 和 Gradle 插件使用全新版本編號
    因此,即使在開發周期的後期,您也可以安全地更新 Android Studio 版本,因為您的項目 AGP 版本與 Android Studio 版本可以採用不同的節奏進行更新。最後,在新的版本系統中,只要您的 AGP 版本保持在穩定版,您或您的團隊就可以在應用項目中更加方便地同時運行穩定版和預覽版 Android Studio。
  • Android studio導入第三方類庫的方法
    1.開發過程中想要導入第三方類庫和Eclipse也是有差別的,我們導入SlidingMenu這個類庫,從github上下載下來解壓到項目目錄下。然後我們需要修改的是我們根目錄的下的settings.gradle這個文件,一定要注意是根目錄下的。
  • Android架構之App組件化方案詳細實踐與總結
    gradle.properties 中配置的欄位都可以在build.gradle文件中直接讀取出來,不用任何多餘的代碼。現在我們在gradle.properties添加了一行代碼,定義一個屬性isModule(是否是組件開發模式,true為是,false為否):# 每次更改「isModule」的值後,需要點擊 "Sync Project" 按鈕isModule=true然後我們在組件的build.gradle文件中讀出這行代碼:if (isModule.toBoolean
  • 跟隨IntelliJ IDEA,谷歌 Android Studio 和 Gradle 插件使用全新...
    因此,即使在開發周期的後期,您也可以安全地更新 Android Studio 版本,因為您的項目 AGP 版本與 Android Studio 版本可以採用不同的節奏進行更新。最後,在新的版本系統中,只要您的 AGP 版本保持在穩定版,您或您的團隊就可以在應用項目中更加方便地同時運行穩定版和預覽版 Android Studio。
  • 一次Android權限刪除經歷
    2.初步定位首先使用android studio查看了打包出來的apk中的Androidmanifest文件,發現其中確實存在RECEIVE_SMS權限,也就是說打包到apk中的Androidmanifest文件並不是app下的該文件,從android開發者官網中合併多個manifest文件的文檔來看,實際上打包到apk中的manifest文件是由多個menifest文件合併而來的,其合併順序如下
  • Android Studio打包apk,aar,jar包
    一片楓葉_劉超的博客地址:http://blog.csdn.net/qq_23547831作者編寫了github項目解析、android源碼分析以及產品研發多個專題,有興趣的可以關注下學習學習~文本我們將講解android studio打包apk,aar,jar包的相關知識。
  • Android 雜知識總結
    在開發中,總會遇到各種不可名狀的問題。限於不同時期對知識點的認識與熟悉度,問題的難度及掌握度也因人而異。
  • Flutter Running Gradle task 'assembleDebug'解決方法
    前言最近用flutter做個app,當運行flutter run的時候,一直卡在這個地方動不了,如下圖:運行時會卡在Running 'gradle assembleDebug, 因為Gradle的Maven倉庫在國外, 可以使用阿里雲的鏡像地址。