Android Gradle (一)Gradle的Android插件入門

本文首發於微信公衆號「後廠村碼農」

相關文章
Gradle核心思想(一)爲什麼現在要用Gradle?
Gradle核心思想(二)Gradle入門前奏
Gradle核心思想(三)Groovy快速入門指南
Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper
Gradle核心思想(五)通俗易懂的Gradle插件講解
Gradle核心思想(六)自定義Gradle插件的三種方式

前言

Gradle核心思想這個系列中我儘量避免了Gradle和Android之間的關聯,這是因爲在瞭解Gradle的核心思想後,可以更好的理解Android Gradle,因此這裏強烈建議先閱讀Gradle核心思想系列。
Android Gradle或者Gradle for Android,實際上指的就是Gradle的Android插件,這一篇我們入個門。

1.什麼是Gradle的Android插件

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

  • 代碼和資源易於重用
  • 無論是針對多個apk發行版還是針對不同風格的應用程序,都可以很容易創建應用程序的多個不同版本。
  • 易於配置、擴展和自定義構建過程
  • 良好的IDE集成

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項目視圖如下所示。
Vep71s.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' //1
    }
}

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構建過程中所用到的所有參數。

  • compileSdkVersion:配置編譯該模塊的SDK版本
  • buildToolsVersion:Android構建工具的版本
4.2.1 defaultConfig塊

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

屬性 描述
applicationId 指定App的包名
minSdkVersion App最低支持的SDK版本
targetSdkVersion 基於哪個SDK版本開發
versionCode App內部的版本號,用於控制App升級
versionName App版本名稱,也就是發佈的版本號
testApplicationId 配置測試App的包名
testInstrumentationRunner 配置單元測試使用的Runner,默認爲android.test.InstrumentationTestRunner
proguardFile ProGuard混淆所使用的ProGuard配置文件
proguardFiles 同時配置多個ProGuard配置文件
signingConfig 配置默認的簽名信息
4.2.2 buildTypes塊

buildTypes塊用於配置構建不同類型的APK。
當我們新建一個項目時,在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塊還可以配置很多屬性,常用的配置如下所示。

屬性 描述
applicationIdSuffix 配置applicationId的後綴
debuggable 表示是否支持斷點調試
jniDebuggable 表示是否可以調試NDK代碼
buildConfigField 配置不同的開發環境,比如測試環境和正式環境
shrinkResources 是否自動清理未使用的資源,默認值爲false
zipAlignEnabled 是否開啓開啓zipalign優化,提高apk運行效率
proguardFile ProGuard混淆所使用的ProGuard配置文件
proguardFiles 同事配置多個ProGuard配置文件
signingConfig 配置默認的簽名信息
multiDexEnabled 是否啓用自動拆分多個Dex的功能
4.2.3 signingConfigs塊

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

屬性 描述
storeFile 簽名證書文件
storePassword 簽名證書文件的密碼
storeType 簽名證書的類型
keyAlias 簽名證書中密鑰別名
keyPassword 簽名證書中密鑰的密碼
signingConfigs {
        release {
            storeFile file('C:/Users/liuwangshu/.android/release.keystore')
            storePassword 'android'
            keyAlias 'androidreleasekey'
            keyPassword 'android'
           
        }
4.2.4 其他配置塊

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

描述
sourceSets 配置目錄指向
productFlavors 多個渠道配置
lintOptions Lint配置
dexOptions DEX工具配置
adbOptions adb配置
packagingOptions 打包時的相關配置

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

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主要以下的區別:

  • implementation可以讓module在編譯時隱藏自己使用的依賴,但是在運行時這個依賴對所有模塊是可見的。而api與compile一樣,無法隱藏自己使用的依賴。
  • 如果使用api,一個module發生變化,這條依賴鏈上所有的module都需要重新編譯,而使用implemention,只有直接依賴這個module需要重新編譯。

感謝
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、Java等技術,還有程序員成長類文章。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章