用Gradle 构建你的android程序

简介:

Gradle 构建你的android程序

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

  • 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.

  • Built-in dependency management through Maven and/or 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.

  • Good Tooling API allowing IDE integration

Gradle 基本概念

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

build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	
buildscript {
       
	 repositories {
            mavenCentral()
        }

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

    apply plugin: 'android'

    android {
        compileSdkVersion 17
    }

英语的介绍都来自与 gradle官方文档, 主要后边的中文不是翻译,是补充介绍

buildscript{}

Configures the build script classpath for this project. 说白了就是设置脚本的运行环境

repositories{}

Returns a handler to create repositories which are used for retrieving dependencies and uploading artifacts produced by the project. 大意就是支持java 依赖库管理(maven/ivy),用于项目的依赖。这也是gradle 强力的地方

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. 依赖包的定义。支持maven/ivy,远程,本地库,也支持单文件,如果前面定义了repositories{}maven 库,使用maven的依赖(我没接触过ivy)的时候只需要按照用类似于com.android.tools.build:gradle:0.4,gradle 就会自动的往远程库下载相应的依赖

apply plugin:

声明构建的项目类型,这里当然是android了

android{}

设置编译android项目的参数,接下来,我们的构建android项目的所有配置都在这里完成

构建一个Gradle android项目

首先,你要安装Gradle 1.并且,写进系统的环境变量里面,所有的命令都是默认你已经配好了gradle 的环境。而且,已经已经升级了android sdk 22

要用gradle构建你的有两种方式:(build.gradle 放到项目目录下

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

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

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

个人推荐1,2 方法。。

一个android build.gradle 最基本基本文件

build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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 clean 把android 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 请点击我的gist

build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 代码build.gradle
1
2
3
4
5
6
7
8
buildTypes{
   release {
   signingConfig  signingConfigs.myConfig
     runProguard true
     proguardFile 'proguard-android.txt'
   }
}

gradle clean

gradle build

打多渠道包(Product Flavor)

现在来解释一下上一节的问题,apk目录下的两个apk 的含义

为什么产生了两个apk?

默认的android gralde 插件定义了两种apk 的类型debugrelease,这两种类型的详细对比看附录

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

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

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

你只需要在android{} 补充上

build.gradle
1
2
3
4
5
6
7
8
productFlavors {
	playstore {
			packageName='com.youxiachai.androidgradle.playstore'
	}
	hiapk {
			packageName='com.youxiachai.androidgradle.amazonappstore'
	}
}

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

仅此而已?

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

什么意思? 不知道各位有没有用过友盟做用户统计,如果,你用的是分发渠道分析,你需要修改AndroidManifest.xml 添加上 <meta-data android:value="hiapk" android:name="UMENG_CHANNEL"/>

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

build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 管理的包,也支持指定具体文件,前面已经在上文说过 上面演示的完整 build.gradle gist 里面也有写 你需要加上如下代码即可:build.gradle
1
2
3
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{}更多的介绍

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

    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 结构目录

    tree
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    
    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
    

最后的吐槽

吐槽一下。用ant脚本的(也许你没有接触过。)。在以前你用ant 脚本打包apk的时候需要打包不同包名,你需要用ant 读取AndroidManifest.xml 然后又正则匹配替换里面packagename 参数虽然描述得过程很简单,你真去写的时候你就蛋疼了(对于一个ant外行人来说,个人感觉ant的学习曲线太陡峭了,如果是两年前的我,可能还写得出这样的ant脚本(当年费了很大的功夫学习了一个多星期),不过,因为很少用到(后来知道maven了果断放弃了ant,为什么不在android使用maven? 因为,android 的maven 插件式非官方的,而且现在看来maven 的xml实在很复杂,看起来就头疼))*


本文转自 liam2199 博客,原文链接:  http://blog.51cto.com/youxilua/1204595 如需转载请自行联系原作者

相关文章
|
20天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
1天前
|
JavaScript Java Maven
云效产品使用常见问题之android sdk 构建出aar后,上传到私有maven仓库失败如何解决
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
5天前
|
缓存 移动开发 Android开发
构建高效Android应用:从优化用户体验到提升性能表现
【4月更文挑战第18天】 在移动开发的世界中,打造一个既快速又流畅的Android应用并非易事。本文深入探讨了如何通过一系列创新的技术策略来提升应用性能和用户体验。我们将从用户界面(UI)设计的简约性原则出发,探索响应式布局和Material Design的实践,再深入剖析后台任务处理、内存管理和电池寿命优化的技巧。此外,文中还将讨论最新的Android Jetpack组件如何帮助开发者更高效地构建高质量的应用。此内容不仅适合经验丰富的开发者深化理解,也适合初学者构建起对Android高效开发的基础认识。
2 0
|
5天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
5 0
|
7天前
|
缓存 移动开发 Java
构建高效的Android应用:内存优化策略
【4月更文挑战第16天】 在移动开发领域,尤其是针对资源有限的Android设备,内存优化是提升应用性能和用户体验的关键因素。本文将深入探讨Android应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。
|
11天前
|
存储 数据库 Android开发
构建高效安卓应用:采用Jetpack架构组件优化用户体验
【4月更文挑战第12天】 在当今快速发展的数字时代,Android 应用程序的流畅性与响应速度对用户满意度至关重要。为提高应用性能并降低维护成本,开发者需寻求先进的技术解决方案。本文将探讨如何利用 Android Jetpack 中的架构组件 — 如 LiveData、ViewModel 和 Room — 来构建高质量的安卓应用。通过具体实施案例分析,我们将展示这些组件如何协同工作以实现数据持久化、界面与逻辑分离,以及确保数据的即时更新,从而优化用户体验并提升应用的可维护性和可测试性。
|
13天前
|
XML 移动开发 Android开发
构建高效安卓应用:采用Jetpack Compose实现动态UI
【4月更文挑战第10天】 在现代移动开发中,用户界面的流畅性和响应性对于应用的成功至关重要。随着技术的不断进步,安卓开发者寻求更加高效和简洁的方式来构建动态且吸引人的UI。本文将深入探讨Jetpack Compose这一革新性技术,它通过声明式编程模型简化了UI构建过程,并提升了性能与跨平台开发的可行性。我们将从基本概念出发,逐步解析如何利用Jetpack Compose来创建具有数据动态绑定能力的安卓应用,同时确保应用的高性能和良好用户体验。
15 0
|
15天前
|
监控 API Android开发
构建高效安卓应用:探究Android 12中的新特性与性能优化
【4月更文挑战第8天】 在本文中,我们将深入探讨Android 12版本引入的几项关键技术及其对安卓应用性能提升的影响。不同于通常的功能介绍,我们专注于实际应用场景下的性能调优实践,以及开发者如何利用这些新特性来提高应用的响应速度和用户体验。文章将通过分析内存管理、应用启动时间、以及新的API等方面,为读者提供具体的技术实现路径和代码示例。
|
15天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。
|
15天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。