用Gradle 构建你的android程序

Tags: android gradle

前言

Android gradle 的插件终于把混淆代码的task集成进去了,加上最近,android studio 用的是gradle 来构建项目, 下定决心把android gralde 构建项目的用户指南全部看完, 让不会用gradle 的人也用gradle构建android项目,让打包(注意,打包和构建是两码事)多版本android不再痛苦。最后,题外话:珍惜生命,远离 ant....

Gradle build android 历史

Android Tools主页 ,大概是今年2月份发布adt21.1的时候,忽然在主页发现了New Build System 原来是可以用gradle 来构建android项目,至于gradle是什么(既然点击进来看了应该都知道了吧。) 。然后,又看了一下那时候的RoadMap,还并不支持Proguard 打包,于是就没看了。。。

最近,android studio 发布,终于gradle 0.4 也跟着出来了,于是,先把gradle 学了一遍,然后把Gradle Plugin User Guide也认真阅读了一下,根据我的个人体验,如果你对gradle 毫无了解就去看Gradle Plugin User Guide可 能很多地方都一头雾水,但是并不妨碍你用gradle 打包android应用,只是,出现问题时你就可能很头疼。不过,本篇博文就是让不会gradle 也能用上 gradle 打包android程序,因为,我也不懂gradle,所以,我把我碰到的问题的解决方案都一一列出。

顺便贴上官方为什么使用gradle 的理由

  • Domain Specific Language (DSL) to describe and manipulate the build logic    使用领域驱动语言(DSL)来描述和管理构建逻辑

  • Build files are Groovy based and allow mixing of declarative elements through the DSL and using code to manipulate the DSL elements to provide custom logic.    Build文件基于Groovy语法,允许在DSL中混合使用定义元素并且使用代码管DSL元素实现自定义构建逻辑

  • Built-in dependency management through Maven and/or Ivy.    使用Maven或Ivy来管理构建依赖

  • Very flexible. Allows using best practices but doesn’t force its own way of doing things.    具有很强的伸缩性,提供使用最佳实践,但不会强制按照特定的方式使用

  • Plugins can expose their own DSL and their own API for build files to use.    允许在Build文件中使用插件定义的DSL和API

  • Good Tooling API allowing IDE integration    提供很方便的工具API进行IDE集成

Gradle 基本概念

首先我们将学习几个gradle 的脚本语法,掌握了这几个语法,你就能非常简单的用gradle构建打包android项目了。 首先,我们来看下一个最简单android build.gradle。

build.gradle

buildscript {

 repositories {
        mavenCentral()
    }

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

apply plugin: 'android'

android {
    compileSdkVersion 17
}
  • buildscript:

    Configures the build script classpath for this project. (为工程编译脚本配置类路径,可以理解为配置gradle脚本的基础运行环境)

  • repositories{}    Returns a handler to create repositories which are used for retrieving dependencies and uploading artifacts produced by the project.    返回句柄,用于创建容器。容器将用于下载依赖包以及上传编译后的产品包。

  • dependencies{}    The dependency handler of this project. The returned dependency handler instance can be used for adding new dependencies. For accessing already declared dependencies, the configurations can be used.    项目的依赖,返回依赖句柄实例可以用来增加新的依赖项。如果需要访问一定定义的依赖内容,可以使用这个配置项。

  • apply plugin:    声明构建的项目类型,这里是"android"

  • android{}    编译android的一些编译参数都可以写在这里

构建一个Gradle android项目

首先,你要安装Gradle 1.6,并且需要将Gradle路径配置到系统的环境变量里面,后面的所有的命令都是默认你已经配好了gradle 的环境。而且,已经已经升级了android sdk 22。

可以使用以下方式来进行构建:(build.gradle 放到项目目录下)

  1. 利用adt 22导出 build.gradle.

  2. 复制别人写好的build.gradle 文件.

  3. 根据gradle 规则,手写android 的build.gradle 文件。

下面的build.gradle最基本编译配置文件:

buildscript {

    repositories {
        mavenCentral()
    }

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

apply plugin: 'android'

dependencies {
}

android {

    compileSdkVersion 17
    buildToolsVersion "17"

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

        instrumentTest.setRoot('tests')
    }
}

然后打开控制台,cd到项目目录下:

cd e:\workplace\andoridGradle

如果你是第一次使用gradle构建android项目建议你先使用gradle cleanandroid gradle插件,还有相关依赖包下载下来并且对环境进行初始化,如果出错了,一般可能是下载超时,试多几次即可,最后你会看到如下提示:BUILD SUCCESSFUL。

The TaskContainer.add() method has been deprecated and is scheduled to be remove d in Gradle 2.0. Please use the create() method instead.
:clean UP-TO-DATE

BUILD SUCCESSFUL
Total time: 7.847 secs

完成以上的步骤,就可以正式使用gralde 构建你的android项目了。

然后在命令行中使用gradle build就完成了android项目的构建了。如果,你是照着以上步骤走的话,你将会在项目目录里面看到一个build 的目录,里面就是用gradle构建android项目的全部内容。

最终打包的apk 就在build/apk 目录下了。然后,你会发现,两个apk 一个是 [项目名]-debug-unaligned [项目名]-release-unsigned。如果以上内容你都已经掌握的话,接下来就将详细说说如何利用gralde 打包android apk。

Gralde 打包参数详解

上面说了一大堆东西,其实并不吸引人去使用gradle,如果只是构建项目的话,adt不是更合适吗?如果,你看完以下内容还是这么觉得的话,你就没必要折腾gradle了。。。。。。

打签名包

默认输出 release apk是没有签名的,那么如果我们需要签名的话其实很简单,只需要在android{}里面补充以下内容即可。完整build.gradle请点击这里

signingConfigs {
   myConfig{
     storeFile file("gradle.keystore")
        storePassword "gradle"
        keyAlias "gradle"
        keyPassword "gradle"
    }
}

buildTypes{
    release {
        signingConfig  signingConfigs.myConfig
    } 
}

然后在命令行执行:

gradle clean
gradle build

这次在build/apk 你看到了多了一个[项目名]-release-unaligned,从字面上面我就可以知道,这个只是没有进行zipAlign优化的版本而已。而[项目名]-release就是我们签名,并且是zipAlign过的apk包了.

打混淆包

只需要在原来的基础上加上下面代码即可。完整的proguad.gradle代码。

buildTypes{
   release {
   signingConfig  signingConfigs.myConfig
     runProguard true
     proguardFile 'proguard-android.txt'
   }
}

然后执行

gradle clean
gradle build

打多渠道包(Product Flavor)

现在来解释一下上一节的问题,apk目录下的两个apk 的含义,为什么产生了两个apk?

默认的android gralde 插件定义了两种apk的类型debug和 release。

这个是android gralde 插件 buildTypes{} 方法产生的,默认配置好了两个默认模板,当然你也可以修改,前面我们就是在修改默认的release的配置,让输出release类型的的apk,具有签名和混淆。

对于多渠道包,android 插件提供了一个名为Product Flavor{}的配置,用于进行多渠道打包。

例如,我的android应用有海外版,和国内版本,而且这两个版本的包名是不一样的!!(我就举两个市场的例子安装这个思路,你要打包100个不同的市场只是几行代码的事情。)。

你只需要在android{} 补充上以下内容:

productFlavors {
    playstore {
            packageName='com.youxiachai.androidgradle.playstore'
    }
    hiapk {
            packageName='com.youxiachai.androidgradle.amazonappstore'
    }
}

然后gradle clean,gradle build,在build/apk 下面你会看到一堆的包,命名格式[项目名]-[渠道名]-release

仅此而已?

Product Flavor{} 不只是能改包名那么简单,还能够对编译的源码目录进行切换。

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml添加上

如果,你很多渠道你就会很痛苦,现在用gradle就非常舒服,你只需要在android.sourceSets指定我们的渠道名就行,android gradle插件,会自动打包!!!例如

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

    hiapk {
        manifest.srcFile 'hiapk/AndroidManifest.xml'
    }       
        playstore {
            manifest.srcFile 'hiapk/AndroidManifest.xml'
    }

    instrumentTest.setRoot('tests')

}

然后在命令行执行:

gradle clean
gradle build

省下的时间去喝杯咖啡,睡个觉什么的都好。。。

外部依赖

android gradle对于依赖外部jar包的应用支持maven/ivy 来管理包,也支持指定具体文件,前面已经在上文说过。 你需要加上如下代码即可:

dependencies {
    compile files('libs/android-support-v4.jar')
}

结语

至此,对于用android gradle构建android应用程序,打包android 程序,所需要的所有知识,在以上已经说明,只要你是认真看上面文章的.对于,如何打依赖于android library project的包,可以看附录提供的那个德国人写的例子,而对于build.gradle 里面的代码你需要把0.2, 改为0.4即可。至于用gradle 运行android test case部分的教程,个人感觉写了也白写(我写过关于andorid 测试相关的文章,也录制过视频,所以有这个感觉。),估计不会有人关注,所以,如果你对用gradle 进行android test的话,可以看附录里面提供的官方gradle手册。

附录

对于这部分内容,你读与不读,并不影响你使用gradle 打包android 项目。至于读了的好处就是你能够更好的使用gradle。。

  • 完整的Gradle Plugin User Guide其 中里面有个错误是compile files('libs/android-support-v4.jar') 不是compile file('libs/android-support-v4.jar')教程是基于android gradle0.3 ,在0.4中只是多了混淆打包,这块已经在文中补充了。

  • 一个德国人写的Android-Gradle-Examples

  • dependencies{}手册。

  • debug, release,这两种类型的默认配置如下:

 Property name Default values for debug Default values for release / other
 debuggable true false
 jniDebugBuild false false
 renderscriptDebugBuild false false
 renderscriptOptimLevel 3 3
 packageNameSuffix null null
 versionNameSuffix null null
 signingConfig android.signingConfigs.debug null
 zipAlign false true
  • defaultConfig {} 配置参数列表

 Property Name Default value in DSL object Default value
 versionCode -1 value from manifest if present
 versionName null value from manifest if present
 minSdkVersion -1 value from manifest if present
 targetSdkVersion -1 value from manifest if present
 packageName null value from manifest if present
 testPackageName null app package name + “.test”
 testInstrumentationRunner null android.test.InstrumentationTestRunner
 signingConfig null null
 runProguard false false
 proguardFile  'proguard-android.txt' or 'proguard-android-optimize.txt'  'proguard-android.txt' or 'proguard-android-optimize.txt'
  • build 结构目录

    build/
    ├── apk
    ├── assets
    │   ├── debug
    │   └── release
    ├── classes
    │   ├── debug
    │   │   └── com
    │   │       └── example
    │   │           └── gradle
    │   └── release
    │       └── com
    │           └── example
    │               └── gradle
    ├── dependency-cache
    │   ├── debug
    │   └── release
    ├── incremental
    │   ├── aidl
    │   │   ├── debug
    │   │   └── release
    │   ├── dex
    │   │   ├── debug
    │   │   └── release
    │   ├── mergeAssets
    │   │   ├── debug
    │   │   └── release
    │   └── mergeResources
    │       ├── debug
    │       └── release
    ├── libs
    ├── manifests
    │   ├── debug
    │   └── release
    ├── res
    │   ├── all
    │   │   ├── debug
    │   │   │   ├── drawable-hdpi
    │   │   │   ├── drawable-mdpi
    │   │   │   ├── drawable-xhdpi
    │   │   │   ├── drawable-xxhdpi
    │   │   │   ├── layout
    │   │   │   ├── menu
    │   │   │   ├── values
    │   │   │   ├── values-sw720dp-land
    │   │   │   ├── values-v11
    │   │   │   └── values-v14
    │   │   └── release
    │   │       ├── drawable-hdpi
    │   │       ├── drawable-mdpi
    │   │       ├── drawable-xhdpi
    │   │       ├── drawable-xxhdpi
    │   │       ├── layout
    │   │       ├── menu
    │   │       ├── values
    │   │       ├── values-sw720dp-land
    │   │       ├── values-v11
    │   │       └── values-v14
    │   └── rs
    │       ├── debug
    │       └── release
    ├── source
    │   ├── aidl
    │   │   ├── debug
    │   │   └── release
    │   ├── buildConfig
    │   │   ├── debug
    │   │   │   └── com
    │   │   │       └── example
    │   │   │           └── gradle
    │   │   └── release
    │   │       └── com
    │   │           └── example
    │   │               └── gradle
    │   ├── r
    │   │   ├── debug
    │   │   │   └── com
    │   │   │       └── example
    │   │   │           └── gradle
    │   │   └── release
    │   │       └── com
    │   │           └── example
    │   │               └── gradle
    │   └── rs
    │       ├── debug
    │       └── release
    └── symbols
        ├── debug
        └── release
    88 directories


文章来源:用Gradle 构建你的android程序

本文链接:http://www.4byte.cn/learning/119962/yong-gradle-gou-jian-ni-de-android-cheng-xu.html