Android Studio下項目構建的Gradle配置及打包應用變體

Gradle簡介

  Gradle是一個自動化構建工具,採用Groovy的Domain Specific Language(領域特定語言)來描述和控制構建邏輯。具備語法簡潔、可讀性強、配置靈活等特色。基於Intellij IDEA社區版本開發的Android Studio天生支持Gradle構建程序。Groovy是一種基於JVM的敏捷開發語言,結合了Phthon、Ruby和Smalltalk的許多強大特性。同時,Groovy代碼既可以與java代碼很好地結合,也可以用於擴展示有的代碼。
Gradle有以下特色:html

  • Gradle支持多工程構建和局部構建
  • Gradle支持遠程或本地依賴管理:支持從遠程maven倉庫(項目構建工具、軟件項目管理綜合工具)、nexus私服(局域網內一種特殊的遠程倉庫)、ivy倉庫(管理項目依賴的工具)以及本地倉庫獲取依賴
  • Gradle與Ant、Maven兼容
  • Gradle可輕鬆遷移:Gradle適用於任何結構的工程,能夠在同一個開發平臺平行構建原工程和Gradle工程
  • Gradle使用靈活:Gradle的總體設計是以做爲一種語言爲導向的,而非成爲一個嚴格死板的框架
  • Gradle免費開源
  • Gradle很好的與IDE集成
  • Gradle能夠更容易地集成到自動化構建系統

Android Studio下項目構建的Gradle配置

  在Android Studio下建立一個Android項目,並切換到Project視圖下,能夠看到下圖的項目結構。
這裏寫圖片描述
  紅框標記就是項目中Gradle相關的配置文件,下面咱們從app模塊下的build.gradle開始對各個配置文件進行分析。java

1、app Module下的build.gradle文件說明

  app這個Module下的gradle配置文件,算是整個項目最主要的gradle配置文件,主要配置應用程序屬性、配置應用程序簽名、配置應用程序特性(渠道)、配置應用程序構建類型和配置應用程序依賴,下圖是默認生成的文件內容:
這裏寫圖片描述android

1. 應用插件apply plugin總共有三種類型值,分別以下:

apply plugin: 
‘com.android.application’//這表示此module是一個可運行的應用程序,能夠直接run的
apply plugin: ‘com.android.library’//這表示此module是一個安卓依賴庫的工程,不可直接run
apply plugin: ‘java’//這表示此module是一個java項目,在此module中只能使用java的api

2. 關於android閉包,

  其默認有compileSdkVersion、buildToolsVersion、defaultConfig閉包和buildTypes閉包。
  compileSdkVersion和buildToolsVersion是兩個關於版本描述的參數api

compileSdkVersion 25//指定編譯版本,開發採用的sdk版本
buildToolsVersion 「25.0.2//編譯時採用的構建工具的版本

  defaultConfig閉包參數說明android-studio

applicationId 「com.jointem.variantpackaging」//應用的id,這裏決定應用的惟一標識
minSdkVersion 17//決定此應用可運行的安卓系統最低版本
targetSdkVersion 25//決定此應用可運行的安卓系統最高版本
versionCode 1//應用版本號,更新須要,新包的值要大於老包的方可更新
versionName ‘1.0’//應用版本名,一般用於顯示
testInstrumentationRunner」andrid.support.test.runner.AndroidJUnitRunner」//Android單元測試test runner

  buildTypes閉包參數說明
  關於構建類型buildType,默認有release和debug兩種,默認只顯示release方式,通常是正式發佈的包。markdown

minifyEnabled false//混淆開關
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’// 指定混淆文件及混淆文件規則配置文件的位置

3.關於模塊依賴dependencies

compile fileTree(include: [‘*.jar’], dir: ‘libs’)//編譯文件樹(編譯依賴libs目錄下全部jar)
androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2’, { 
exclude group: ‘com.android.support’, module: ‘support-annotations’ 
})
compile ‘com.android.support:appcompat-v7:24.2.1’//是從repository(默認是jCenter())裏下載一個依賴包進行編譯並打包
compile ‘com.android.support.constraint:constraint-layout:1.0.0-beta5’
testCompile ‘junit:junit:4.12’// 僅僅是針對單元測試代碼的編譯編譯以及最終打包測試apk時有效,而對正常的debug或者release apk包不起做用
compile project(‘:andr-library’)//是將另外一個module進行編譯並打包

  其實,app下的腳本對應的是項目的Project Structure對話框中的設置,從左到右依次是屬性、簽名、渠道特性、構建類型和依賴,快捷鍵Ctrl+Shift+Alt+S(Windows/Linux),以下。
這裏寫圖片描述網絡

2、library Module下的build.gradle配置

  除了app Module,每個Module也都有一個gradle配置文件,語法都同樣,區別在於開頭聲明的是apply plugin: ‘com.android.library’,代表該Module是以依賴模塊的形式存在。閉包

3、全局配置文件

  全部的全局配置文件都會放置在項目的根目錄下,包括忽略文件、本地配置文件、gradlew的批處理文件以及項目gradle相關的配置文件。app

1.gradle配置文件gradle-wrapper.properties,默認內容以下:

#Thu Mar 09 16:27:37 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

  此配置文件中主要聲明瞭gradle的目錄與下載路徑以及當前項目使用的gradle版本,這些默認的路徑咱們通常不會更改的,這個文件裏指明的gradle版本不對也是不少導包不成功的緣由之一。框架

2.關於project下build.gradle配置文件

  整個項目的gradle基礎配置文件,用來配置項目的構建任務,內容以下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.// 項目構建文件,能夠在各子項目/模塊添加經常使用的配置選項。
buildscript {
    //Android插件從這個倉庫下載
    repositories {
        jcenter()//依賴倉庫源的名稱,兼容maven的遠程中央倉庫
    }
    //項目依賴
    dependencies {
        //android gradle插件
        classpath 'com.android.tools.build:gradle:2.3.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
allprojects {
    //此處配置Project中默認的倉庫源,包括每一個module的依賴,無需每一個module單獨配置
    repositories {
        jcenter()
    }
} //打包前執行clean任務 //任務類型是Delete //clean任務就是刪除項目根目錄下的build目錄中的文件
task clean(type: Delete) {
    delete rootProject.buildDir
}

3.關於Gradle配置文件gradle.properties

  gradle.properties是Gradle的配置文件,build.gradle經過讀取這個文件配置的參數來進行相應構建,可在此配置文件中配置一些全局參數(全局代理)。默認文件內容以下:

# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# 配置守護進程的jvm參數
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m

#配置完成後,Gradle將在並行模式下運行(並行編譯)
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
#http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

4.關於全局配置文件setting.gradle

  默認文件內容include ‘:app’。是項目的全局配置文件,主要聲明一些須要加入構建的模塊。在Android studio中一般都是默認自動在此文件中添加依賴的module。

Android Studio下的依賴方式

1、Project Structure

  按快捷鍵Ctrl+Shift+Alt+S(Windows/Linux),打開Project Structure彈窗。
這裏寫圖片描述
  在Dependencies下有個scope,這裏能夠選擇依賴的方式,可選項有Compile、Provided、APK、Test compile、Debug compile和Release compile,下面分別對這些可選項進行簡單說明。

  • Compile:是對全部的build type以及favlors都會參與編譯而且打包到最終的apk文件中,是從repository(默認是jCenter())裏下載一個依賴包進行編譯並打包。
  • Provided:Provided是對全部的build type以及favlors只在編譯時使用,相似eclipse中的external-libs,只參與編譯,不打包到最終apk,是提供給那些只編譯不打包場景的命令。就是我在編譯的時候對某一個jar文件有依賴,可是最終打包apk文件時,我不想把這個jar文件放進去,能夠用這個命令。
  • APK:只會打包到apk文件中,而不參與編譯,因此不能再代碼中直接調用jar中的類或方法,不然在編譯時會報錯。
  • Test compile:僅僅是針對單元測試代碼的編譯編譯以及最終打包測試apk時有效,而對正常的debug或者release apk包不起做用。
  • Debug compile:僅僅針對debug模式的編譯和最終的debug apk打包。
  • Release compile:僅僅針對Release 模式的編譯和最終的Release apk打包。

2、關於Compile的兩個子參數:

  • compile files:是從本地的libs目錄下尋找picasso-2.4.0.jar這個文件進行編譯並打包。相似的命令有compile fileTree(dir: 'libs', include: '*.jar'),即,將libs目錄下全部jar文件進行編譯並打包。
  • compile project:是將另外一個module(等同eclipse中的library)進行編譯並打包。

打出多變體包

1、爲何要打包變體包?

  在開發過程當中常常遇到多個環境切換的問題,好比,正在鏈接測試環境進行調試,此時又想看生產環境的數據顯示,一般的處理方式是卸掉測試環境的而後運行一個生產環境的包。咱們都知道,build一個大項目,直到安裝到手機上,整個過程是很耗時的。若是同一臺手機上能夠同時安裝同一個應用的多個不一樣環境的apk,那麼,當想看其它環境的數據時,就不須要從新卸載再安裝了(同理,同一應用,須要不一樣版本的安裝包[免費版/收費版]時,也能夠這樣處理,而無需爲不一樣版本建立不一樣的分支)。

2、打包變體包的條件

  在建立完一個項目後,咱們在app這個module下的build.gradle中的android節點下defaultConfig節點中,能夠看到一個applicationId屬性,默認的 applicationId 和 AndroidManifest.xml 中的 package 屬性是相同的。applicationId 和 packageName 它們各自表明什麼?爲什麼會是相同的呢?其實,package 表明了 java 代碼中的包名,在應用中的資源,就是經過package標識的(好比R文件,包名.R);applicationId 則表明了應用中的惟一標識,和應用簽名一塊兒用來區別於其餘應用。
  在手機上,系統一樣是經過applicationId和簽名來標識一個app的。因此,咱們只要在打包apk時,使得應用之間的applicationId和簽名各不相同,就可以實現同一個應用的不一樣變體同時安裝在同一臺手機上了。同時,爲了更好的區分給個變體應用,咱們還能夠經過對佔位符的使用,使用gradle配置不一樣的資源文件、不一樣的應用名稱與圖標、不一樣的java文件等有區別的屬性,打出不一樣的變體包。

3、打出變體包的步驟

1.配置簽名、渠道(applicationId)

  選擇app module,選擇Signing選項卡,首先配置好了這兩個變體版本的簽名文件,文件名可任意取(見名知意)。
這裏寫圖片描述
  簽名屬性字段描述:

  • keyAlias//指定簽名文件的別名
  • keyPassword//指定簽名文件的別名配對密碼
  • storeFile//簽名文件路徑
  • storePassword//簽名文件的密碼

  切換到Flavors選項卡,配置變體包的相關屬性,因爲下一步建立資源文件夾時,須要與這裏的文件名對應,因此此處的取名儘可能簡約。這裏我建立兩個命名dev和rea的Flavor,全部的Flavor都會複寫defaultConfig中的屬性,因此能夠看到我並無填寫其中的一些屬性。在這裏很是關鍵的一點,是對不一樣的變體設置不一樣的applicationId,並選擇對應的Signing Config。
這裏寫圖片描述

2.新建不一樣變體的sourceSet

  在修改完變體的配置文件後,咱們還須要再項目的src文件夾下,新建以咱們的Flavor名稱命名的文件夾,並在這些文件夾下新建如main中相同的目錄結構。
這裏寫圖片描述
  咱們正常編寫項目都是寫在main這個sourceSet下的,可是若是咱們的項目的變體有不一樣的資源文件、Java文件時,咱們就須要使用不一樣的sourceSet來區別開。
  須要注意的是,Flavor下的資源文件會與main中的合併,若是存在重複,則Flavor中優先級高於main中。咱們能夠將不一樣變體中共用的資源存放在main中,只將不一樣的內容存放在flavor的sourceSet中。
  若是不一樣變體有內容不一樣的Java文件則要注意,須要將這個Java文件放置到每一個flavor 的sourceSet文件夾下,main中不能夠有這個Java文件,若是main中也存在此文件,編譯時會提示文件重複。好比說有兩個變體,有着不一樣的TargetActivity.java,那麼main中就不能有這個文件了,須要把這個Java文件放到各個flavor的sourceSet下,同時這個Java文件在sourceSet中要按照main中的包結構保存。

3.關於配置不一樣的launcher圖標和應用名

  經過以前的操做,已經能夠有效區分變體包的applicationId、Signing Config和java文件,那麼應用logo和name又該如何處理呢,這裏有兩種方法。

1)配置不一樣的資源:咱們可使用相似於處理java文件的方法,在不一樣的sourceSet中配置string.xml中app_name屬性,在mipmap文件夾中放置對應的ic_app.png圖標資源。不過當咱們須要更換啓動圖和應用名而變體包又比較多的狀況下,這種方法會比較麻煩,由於咱們要到每個sourceSet資源文件下去對應的修改,若是使用佔位符的方式,那麼會變得簡單一些。
2)使用佔位符的方式:在AndroidManifest文件中使用佔位符而後在flavor中直接配置,在flavor中使用的屬性是manifestPlaceholderss(manifestPlaceholders =[NAME1:VALUE1]),而圖標資源和應用名稱咱們均可以直接放置到main中。
結果以下圖:
這裏寫圖片描述

4、Debug時選擇變體

1.選擇要調試的應用

  經過以前的操做,已經成功配置了多個變體,那麼問題來了,這麼多個變體,咱們在debug的時候,咱們怎麼選擇要debug的變體呢?這裏有兩種方式進行切換。

  • 選擇Build->Select Build Variant,在左下角會顯示出Build Variant視圖,點擊選擇要編譯的變體。
    這裏寫圖片描述
  • 另外一種方式則是直接點擊左下角Build Variant選下卡,以後的操做同上。

2.須要注意的的地方

  • 在這裏能夠看到有4個變體,這是爲何呢?咱們明明只配置了兩個變體呀?在這須要提到Build Type配置,這個選項卡下默認有兩個類型,分別是debug和release,變體包的數量正是(build type數量)*(flavor數量)。
    這裏寫圖片描述
  • 當你選擇完要編譯的變體後,會發現未被選中的變體下會報找不到資源的錯誤,這是很正常的,當被選中以後就會變成正常的工程文件夾樣式了,其這種報錯也並不會影響咱們進行批量打包。

5、經常使用gradlew命令

  首次運行命令行,沒有gradle的要下載的哦,下載須要的時間根據網絡情況而定。

1.八個經常使用命令:

  • ./gradlew -v //查看gradle版本
  • ./gradlew assembleDebug //編譯並打出Debug版本的包
  • ./gradlew assembleRelease //編譯並打出Release版本的包
  • ./gradlew build //執行檢查並編譯打包,打出全部Release和Debug的包
  • ./gradlew clean //刪除build目錄,會把app下面的build目錄刪掉
  • ./gradlew installDebug //編譯打包並安裝Debug版本的包
  • ./gradlew uninstallDebug //卸載Debug版本的包
  • ./gradlew -info //使用-info查看任務詳情

2.命令行終端Terminal下執行打包命令

  咱們直接利用./gradlew build打出全部的變體包,在Terminal終端下鍵入./gradlew build命令,須要等待大概20秒鐘左右,當看到終端打印出BUILD SUCCESSFUL,說明打包任務執行完成,打開指定的apk生成目錄(默認app/build/outputs/apk),就能夠看到已經打出的apk。
這裏寫圖片描述
  將兩個release包都安裝到同一臺手機,能夠發現能同時存在,而且都能正常打開運行。
這裏寫圖片描述

3.關於打包須要注意的坑

  若是項目中存在使用Library Module,而且Library Module中manifest下的application也存在與app Module下的application相同的屬性標籤,那麼會報manifest.xml合併錯誤的提示,以下。
這裏寫圖片描述

  • 緣由:這是由於AS的Gradle插件默認會啓用Manifest Merger Tool,若Library項目中也定義了與主項目相同的屬性(例如默認生成的android:icon和android:theme),則此時會合並失敗,並報上面的錯誤。
  • 處理辦法:在Manifest.xml的application標籤下添加tools:replace=」android:icon, android:theme」(多個屬性用,隔開,而且記住在manifest根標籤上加入xmlns:tools=」http://schemas.android.com/tools」,不然會找不到namespace哦)。

注:本篇博客純屬我的筆記,若是錯誤之處,還望幫忙指正,謝謝!


相關文章
相關標籤/搜索