使用Gradle構建Android項目

新項目中,使用了Google I/O 2013發佈的新工具,使用Gradle構建android項目,而且在新版的Intellig IDEA以及google的Android Studio對其支持。本文就介紹一下怎麼使用gradle構建android項目,進行多個版本編譯。java

Gradle是什麼?

Gradle是以Groovy爲基礎,面向java應用,基於DSL語法的自動化構建工具。是google引入,替換ant和maven的新工具,其依賴兼容maven和ivy。
使用gradle的目的:android

  • 更容易重用資源和代碼;git

  • 能夠更容易建立不一樣的版本的程序,多個類型的apk包;github

  • 更容易配置,擴展;api

  • 更好的IDE集成;app

環境需求

Gradle1.10或者更高版本,grale插件0.9或者更高版本.
android SDK須要有Build Tools 19.0.0以及更高版本maven

Gradle基本結構

使用ide建立的gradle構建的項目,會自動建立一個build.gradle,以下:ide

buildscript {
    repositories {
        mavenCentral()
    }

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

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"
}

能夠看到,構建文件主要有三個區域:工具

buildscript{...}測試

Configures the build script classpath for this project. 設置腳本的運行環境

apply plugin: 'android'

設置使用android插件構建項目

android{...}

設置編譯android項目的參數

任務task的執行

一般會有如下任務:

  • assemble The task to assemble the output(s) of the project(輸出一個項目文件,android就是打包apk)

  • check The task to run all the checks.(運行檢查,檢查程序的錯誤,語法,等等)

  • build This task does both assemble and check (執行assemble和check)

  • clean This task cleans the output of the project(清理項目輸出文件)

上面的任務assemble,check,build實際上什麼都不作,他們其實都是其餘任務的集合。

執行一個任務的方式爲gradle 任務名, 如gradle assemble

在android項目中還有connectedCheck(檢查鏈接的設備或模擬器),deviceCheck(檢查設備使用的api版本)

一般咱們的項目會有至少生成兩個版本,debug和release,咱們能夠用兩個任務assembleDebug和assembleRelease去分別生成兩個版本,也可使用assemble一會兒生成兩個版本。

gradle支持任務名縮寫,在咱們執行gradle assembleRelease的時候,能夠用gradle aR代替。

基本的構建定製

咱們能夠在build.gradle文件中配置咱們的程序版本等信息,從而能夠生成多個版本的程序。
支持的配置有:

  • minSdkVersion 最小支持sdk版本

  • targetSdkVersion 編譯時的目標sdk版本

  • versionCode 程序版本號

  • versionName 程序版本名稱

  • packageName 程序包名

  • Package Name for the test application 測試用的程序包名

  • Instrumentation test runner 測試用的instrumentation實例

例如:

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        versionCode 12
        versionName "2.0"
        minSdkVersion 16
        targetSdkVersion 16
    }
}

目錄配置

默認狀況下項目目錄是這樣的 有兩個組件source sets,一個main,一個test,對應下面兩個文件夾。 src/main/ src/androidTest/

而後對於每一個組件目錄都有兩個目錄,分別存儲java代碼和資源文件 java/ resources/

對於android項目中呢,對應的目錄和文件是 AndroidManifest.xml //該文件src/androidTest/目錄下不須要,程序執行時會自動構建 res/ assets/ aidl/ rs/ jni/

若是須要上面這些文件,可是不是在上面所說的目錄,則須要設置。

sourceSets {
    main {
        java {
            srcDir 'src/java'
        }
        resources {
            srcDir 'src/resources'
        }
    }
}

能夠給main或者test設置根目錄,如

sourceSets {
        androidTest.setRoot('tests')
    }

能夠指定每種文件的存儲路徑

sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    }

特別是咱們的ndk生成的.so文件,一般咱們不是放到jni目錄中的,咱們須要設置一下

sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

簽名配置

能夠給不一樣類型進行不一樣的配置,先看示例:

android {
    signingConfigs {
        debug {
            storeFile file("debug.keystore")
        }

        myConfig {
            storeFile file("other.keystore")
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
    }

    buildTypes {
        foo {
            debuggable true
            jniDebugBuild true
            signingConfig signingConfigs.myConfig
        }
    }
}

上面的配置文件配置兩個類型,一個時debug類型,一個時本身的自定義類型。兩個分別使用了不一樣的簽名,同時對於生成密鑰,要填寫設置的密碼。

代碼混淆設置

直接看代碼:

android {
    buildTypes {
        release {
            runProguard true
            proguardFile getDefaultProguardFile('proguard-android.txt')
        }
    }
}

以上是使用默認的proguard文件去進行混淆,也可使用本身編寫的規則進行混淆,proguardFile 'some-other-rules.txt'

依賴配置

程序中會依賴別的包,或者程序,須要引入別的類庫。前面也說到了,支持maven。 對於本地的類庫,能夠這樣引入:

dependencies {
    compile files('libs/foo.jar')   //單個文件
    compile fileTree(dir: 'libs', include: ['*.jar'])  //多個文件
}

android {
    ...
}

對於maven倉庫文件:

repositories {
    mavenCentral()
}


dependencies {
    compile 'com.google.guava:guava:11.0.2'
}

android {
    ...
}

輸出不一樣配置的應用

看代碼:

android {
    ...

    defaultConfig {
        minSdkVersion 8
        versionCode 10
    }

    productFlavors {
        flavor1 {
            packageName "com.example.flavor1"
            versionCode 20
        }

        flavor2 {
            packageName "com.example.flavor2"
            minSdkVersion 14
        }
    }
}

經過以上設置,咱們能夠輸出不一樣的保命不一樣的版本號,以及最小sdk的程序包。固然咱們能夠根據本身的需求去作其餘的不一樣

生成多個渠道包(以Umeng爲例)

個人完整配置文件

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}
apply plugin: 'android'

repositories {
        mavenCentral()
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    lintOptions {
        abortOnError false
    }


//簽名
    signingConfigs {
        //你本身的keystore信息
        release {
            storeFile file("×.keystore")
            storePassword "×××"
            keyAlias "××××"
            keyPassword "×××"
        }
    }

    buildTypes {

        debug {
            signingConfig signingConfigs.release
        }

        release {
            signingConfig signingConfigs.release
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    //渠道Flavors,我這裏寫了一些經常使用的,大家本身改
    productFlavors {
        //GooglePlay{}
        //Store360{}
        //QQ{}
        //Taobao{}
        //WanDouJia{}
        //AnZhuo{}
        //AnZhi{}
        //BaiDu{}
        //Store163{}
        //GFeng{}
        //AppChina{}
        //EoeMarket{}
        //Store91{}
        //NDuo{}
        xiaomi{}
        umeng{}
    }

}


//替換AndroidManifest.xml的UMENG_CHANNEL_VALUE字符串爲渠道名稱
android.applicationVariants.all{ variant ->
    variant.processManifest.doLast{

        //以前這裏用的copy{},我換成了文件操做,這樣能夠在v1.11版本正常運行,並保持文件夾整潔
        //${buildDir}是指./build文件夾
        //${variant.dirName}是flavor/buildtype,例如GooglePlay/release,運行時會自動生成
        //下面的路徑是相似這樣:./build/manifests/GooglePlay/release/AndroidManifest.xml
        def manifestFile = "${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml"

        //將字符串UMENG_CHANNEL_VALUE替換成flavor的名字
        def updatedContent = new File(manifestFile).getText('UTF-8').replaceAll("UMENG_CHANNEL_VALUE", "${variant.productFlavors[0].name}")
        new File(manifestFile).write(updatedContent, 'UTF-8')

        //將這次flavor的AndroidManifest.xml文件指定爲咱們修改過的這個文件
        variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.dirName}/AndroidManifest.xml")
    }
}

以上的功能就是替換個人Manifest中的umeng渠道標示,同時去生成不一樣的apk包。

最後說明

程序在buid的時候,會執行lint檢查,有任何的錯誤或者警告提示,都會終止構建,咱們能夠將其關掉。

lintOptions {
        abortOnError false
    }

最後PS一下

本人使用gradle確實方便不少,雖然電腦配置低,build的時候比較慢。
內容呢,主要時參考谷歌官方的文檔。
關於怎麼安裝,沒有講到,能夠參考這篇文章:http://stormzhang.github.io/android/2014/02/28/android-gradle/

附上我參考的文檔,沒看懂的能夠去看看。http://tools.android.com/tech-docs/new-build-system/user-guide

原文地址:http://blog.isming.me/blog/2014/05/20/android4gradle/,歡迎轉載,轉載請註明出處。

相關文章
相關標籤/搜索