您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  要资料 文章 文库 Lib 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
 
     
   
 订阅
  捐助
IDEA 及 Gradle 使用总结
 
作者:PowerfulYi 来源:CSDN 发布于 2015-9-9
    评价:      
 

自动编译组件

目前Android开发的主流开发工具是 Eclipse 和 IDEA

目前主流的自动化打包工具时 ant,maven,gradle。

maven工具中有自己的依赖仓库维护,很多开源支持包在上面都有维护(国内的除外)

gradle是近年来发展起来自动化构建应用,解决 ant 构建上的繁琐代码,并且也支持读取maven的配置形式,依赖maven的支持包结构

好了,平时你们使用 eclipse 发布的时候,不要说你没用过自动构建,eclipse 的 android项目是用ant的构建方式。如果你要加渠道发布,你就需要自己写 ant 的脚本。

maven自动构建,目前大多数用在 javaweb 项目,安卓项目用的不多。

eclipse 的构建应用大多使用 ant,maven,gradle也有相关支持。Android的项目默认使用 ant 进行构建

在 IDEA 中,可以使用 ant 方式构建 android应用,也能使用 gradle 方式构建,目前主流支持都是 gradle 方式。

IDEA 默认使用 gradle 工具做 android 的构建程序,你试试在新建应用的时候选择 Application Module 而不是 Gradle:Android Module 看看,你会发现,工程项目和 eclipse 没什么区别。而且包含 ant 的脚本文件。(如下图)

Gradle Module原理

IDEA 支持 ant,maven,gradle 工具来构建引用。目前 Android 应用在 as下编码基本使用 gradle 进行构建,本章将基于这个思路讲解那些内容属于 IDEA,那些内容属于 gradle 。

首先,我们建立一个 Gradle:Android Module 来看看 Gradle 项目结构。

得到的目录结构如下:

其中根目录是一个project,下面的app目录是其中一个module。

.gradle .idea 是在分别在 gradle ,IDEA 运行时候会生成的文件,一般这样的文件也不会纳入源代码管理之中。

app文件夹,是其中一个module,里面的文件内容与父类差不多,若没有定义,则在项目中使用父类的设置(意思就是,里面也能包含build.gradle、gradle.properties、setting.gradle 等相关gradle文件,怎么理解?其实每一层都是一个module,整个项目是一个大的 module 而已)

gradle 文件夹,用于保存gradle 下载路径的配置文件位置,用于没有gradle环境的环境初始化使用

build.gradle 项目的编译环境配置,比如制定项目依赖的lib包。

gradle.properties 配置gradle运行环境的文件,比如配置gradle运行模式,运行时jvm虚拟机的大小

gradlew && gradlew.bat 代替gradle 命令实现自动完成gradle环境搭建。配合gradle文件夹的内容,会降到IDEA如何搭配gradlew使用。

local.properties 配置android NDK,SDK的地方,恩,非android项目可能没有这个文件,这个路径根据不同想电脑不同,一般也不会纳入源代码管理之中,一般可以写一个local.properties.simple 文件,告知需要修改该文件名并写上本地SDK NDK 路径。simple文件纳入源码管理之中。

setting.gradle 子项目包含文件,声明当前目录下含有什么module,当然你的app底下加上这样的文件,也能继续在app底下加module。和我第点说的,整个project就是一个大的module,每个module下面还能包含相应的module。如果你理解这个了,其实app目录单独作为一个项目管理也是可以的,,把相应的配置文件配上而已,相当于主目录应用 android 的gradle plugin (下一点会说到这个)

gitignore 该文件是源码管理的配置文件,不在该文讲解。

既然gradle 是多 module形式,那么我们来看看 setting.gradle 配置的内容

从上面目录的配置文件内容来看,整个project也算是一个module,如果改module底下还有module,就可以通过setting.gradle配置进来,使得该module底下的gradle,从app module底下可以看出,module最少要含有 build.gradle文件,这个module的项目编译文件,该module依赖什么插件对该目录进行编译都在此配置,比如android与android-library,其他内容可继承父类的

Gradle 与 IDEA 的关联性

上面介绍了gradle项目的目录结构,以及module的模式,接下来,了解一下IDEA如何与gradle项目关联上来的。

idea的项目,在建立或者导入的时候,就已经确定他是基于什么自动构建工具的项目。新建的时候,使用 gradle androiw module 说明他是 gradle 自动构建的项目,那么导入的时候也是一样。我们看看下面的项目导入图,在选择项目地址之后,我们看到一下的内容。

如果你的项目里面包含了gradle的相关文件,就可以选择 import project form external model 导入IDEA了,如果项目只有源码,没有包含自动构建的相关信息,你只能选择 Create project form existing sources 了,让他生成自动构建工具需要的文件。

你可能会想,想gradle里面的依赖包,我不知道有哪些,怎么办。好吧,你私下里就骂骂作者吧,上传了源码不上传自动构建相关的文件,导致项目依赖不完整,还得找资料自己完善,所以这里也希望广大开源代码爱好者,在分享你的作品的时候,希望能够分享完整的项目信息,别只有源码,让人跑不起来项目(牢骚说多了)。

那么下一步是什么呢:

恩,是不是似曾相识?你没看错,在新建项目的时候也有这个选择,这个是选择自动编译的工具的方式。

如果你到官方下载 gradle 绿色包,解压到某个目录,你可以使用 gradle distribution,并设定 Gradle home 目录,这样 IDEA 构建编译项目的时候,就使用你设定的gradle版本进行。

说到这里,我觉得该说说 use default gradle wrapper 记得新建项目的时候也是使用 use default gradle warpper,这时候,上面目录说到的三个文件。

gradle/
gradlew
gradlew.bat

如果使用这种方法,IDEA会调用项目根目录 gradlew 或者 gradlew.bat (根据linux,windows,osx自动选型)代替原生的 gradle 方法做自动构建。

这两个文件做了什么事情呢:

解析 gradle/wrapper/gradle-wrapper.properties 文件,获取项目需要的 gradle 版本下载地址

判断本地用户目录下的 ./gradle 目录下是否存在该版本,不存在该版本,走第3点,存在走第4点

下载 gradle-wrapper.properties 指定版本,并解压到用户目录的下 ./gradle 文件下

利用 ./gradle 目录下对应的版本的 gradle 进行相应自动编译操作

看了上面的原理,应该明白了,如果你自己下载 gradle 让idea 导入项目的时候使用。那么其他人就不知道你使用什么版本的gradle版本进行自动编译,如果使用 项目目录自带的 gradlew 的话,gradlew 就会自动完善 gradle 的安装,若需要更新 gradle 的版本,只需要修改 gradle/wrapper/gradle-wrapper.properties 文件内的下载链接即可。而且gradlew的版本和 android 版本是需要适配的,在自己电脑维护需求不同版本的 gradlew 也是一个麻烦的事情。

而且这样的好处也有一个,当你在新电脑上下载你的源码进行编译时,你完全可以不依赖IDE开发工具,直接在项目目录下使用 ./gradlew build 即可对源码进行编译,因为它会自动下载 gradle 进行调用,可以使得新电脑较快完成项目开发环境适配(对网络依赖较强,希望带上vpn,这就是为什么你们在新建项目时需要去下载gradle,还比较慢的原因,我们一起来 f-u-c-k-g-f-w)

当然,导入项目需要能够选上 use default gradle wrapper 的前提是存在上面一个gradle文件夹与gradlew、gradew.bat

既然可以选择使用 gradlew 来管理 gradle 或者手动指定 gradle 工具,那么已经存在的项目如何更改?

这个问题,我曾在 idea 13 版本上有找到,但是在 idea 14 上面没找到相应的变更设置。谁要是找到了,记得留言告知我一声。

在导入项目或者新建项目的时候,idea 会根据 build.gradle 文件更新 *.iml 项目文件,有时候,你会发现,新增一个jar包,但是无法读取jar包内容,因为对于 gradle 来说,jar包属于项目外依赖,包括maven拓展包,都是属于项目外依赖,需要修改build.gradle 文件,当你加入新的 jar包,或者添加了 maven支持包,在idea上面都会提示需要进行同步

恩,上图你看到的,是我模拟添加一个jar包之后,随便加了一个空格,文件上提示需要进行 gradle 项目与 idea项目文件同步,点击 sync now 之后,idea 会根据 gradle 文件重新更新 .idea 目录以及 *.iml 文件,让idea 可以识别引入的 资源。

这也就是为什么有人说加入一个jar包确没有自动提示,而重新打开idea之后就能够提示使用jar内的方法了,因为重新打开idea,开发工具会重新同步 build.gradle 的内容

Gradle Android Plugin Version与 Gradle Version对应

gradle只是一个自动化编译工具,它需要以来插件来识别这是什么项目,用什么方式去编译的。我们来看看 build.gradle 与 app/build.gradle 的设置看看。

不知道你们会不会奇怪,在app里面的 build.gradle 中,缺少了 buildscript 与 allproject 的设置,恩,没错,我删掉了,因为这个设置是可以继承父项目的 build.gradle

其中父类的整个项目需要依赖插件 com.android.tools.build:gradle:0.14.2 最后是版本号。(目前AS的版本号已经是1.0.0了)

这个插件的版本号与gradle调用编译时是有依赖关系的,插件的版本越高,需要更多gradle的新特性,新的gradle特新就需要新版本的gradle才能支持。

这时候,回到上一节的内容,如果要使用android项目自动编译的新特性,如果选择不同的gradle指向方式,那么你就要做不同的处理

下载不同版本的gradle对不同的项目的不同版本做插件与gradle的对应维护,如果其他人使用你的项目,你还要告知他使用什么版本以上的gradle才能使用这个插件。

把对应关系一次弄好之后,更新gradle/wrapper/gradle-wrapper.properties下载地址,利用gradlew自动使用相应版本的gradle,这样gradlew版本的需求就跟着源码管理一直保留到其他人的电脑商。

目录格式

先来看看eclipse的完整目录与IDEA的完整目录结构(当然,IDEA看的目录时基于module的目录设置的,而不是根据总项目的目录设置的)

eclipse目录

IDEA(AS)目录

按照Android开发的目录,区分为以下的目录格式:

上面所展示的内容就是目前Android用到的所有资源文件类型。为什么要把项目根目录列出来?这个到后面渠道包的时候需要用到。可是也可能也会问到,为什么项目根目录会有两级。src 第一级我的理解是项目源码相关都在这里,第二级,认为是主项目源码在 main 目录,根据系统完善性,应该针对主项目添加测试项目的源码,所以新的代码里面在 main 目录同级的地方会有 tests 目录,用于测试项目的目录源码维护。如果有渠道,还可以为渠道包新建项目目录去坐项目自定义。

1. 其中adil是跨进程通信使用的

2. jni文件夹是存放dnk编译的c或者cpp文件

3. jnilibs文件,就是平时jni接入使用的 *.so库。需要里面是需要包含平台文件夹的。入下图所示

当我们要从eclipse里面转移到as的时候,是可以通过gradle来从新定义以上路径的。在module/build.gradle文件里面有这么一段设置默认设置,如果按照缺省,可以不写。

sourceSets
{


    main.setRoot('src/main')


    main
{


        manifest.srcFile
'[mainRoot]/AndroidManifest.xml'


        java.srcDirs
=
['[mainRoot]/java']


        resources.srcDirs
=
['[mainRoot]/java']


        aidl.srcDirs
=
['[mainRoot]/aidl']


        res.srcDirs
=
['[mainRoot]/res']


        assets.srcDirs
=
['[mainRoot]/assets']


        jni.srcDirs=['[mainRoot]/jni']


        jniLibs.srcDirs
=
['[mainRoot]/jniLibs']


    }

所示需要适应eclipse的目录格式,可以写成:

sourceSets {
//main.setRoot('src/main') 因为下面的路径全部被定义了,所以这个方法已经不起作用了。
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jni.srcDirs=['jni']
jniLibs.srcDirs = ['libs']
}

你一定奇怪,为什么libs 的jar包没有目录呢?没错,还记得我上面写过的,对于 gradle android 项目来说,jar包和library支持,属于android项目的外部支持,通通由 Gradle 配置文件去管理。上图的最后一段说明这一切。

Jar支持、Library支持、仓库插件

说到 library ,不得不说说项目类型。

在项目根目录,我们引入了 android 插件:com.android.tools.build:gradle:0.14.2

我们具体看上图 build.gradle 的第一行代码:

apply
plugin:
'com.android.library'

这是说明这个 module 项目说明 android-library 项目,我看过其他的项目,gradle module 是可以依赖多个 plugin 让这个项目成为多种类型的项目。

如果是一个普通android项目,会是这样的代码:

apply plugin: 'com.android.applition'

那么 android 项目 gradle 中依赖 jar libs 又三种方法:

#1 依赖项目相对路径的jar包,当然,你可以换成全路径

compile
files('libs/something_local.jar')

#或者依赖libs目录下的所有jar包

compile
fileTree(dir:
'libs',
include:
['*.jar'])

#2 依赖maven仓库中的支持包(目前很多好的都在maven进行管理,比如
 v4,v7支持包)

compile
'com.android.support:appcompat-v7:20.0.0'

#3 依赖其他library
 module

compile
project(':jiechic-library')

这么一看,我这个 jiechic-library 其实就是一个module,与app同级,使用的是 apply plugin: ‘com.android.library’ 形式的一个安卓 library 。

有时候,你可能新加入一个

很多开源仓库不懂怎么加?maven插件添加不在这篇文章的讨论范围了。你在搜搜可否?

编译过程及渠道模式

ant 的的编译目录基于当前工作目录进行,如果你需要自定义渠道,你需要编写 ant 脚本代码,去替换当前目录的文件,而且当前目录的文件你还需要进行保存一次。若出错了,你还得在本地目录进行恢复。

gradle 的编译方式,是根据基础项目内容,以及渠道信息 ,将相关代码文件拷贝合并到 build 目录下,然后在build 目录下进行编译。在此设计小文件多文件的平凡拷贝更新,则正常编译速度让很多人觉得,IDEA 开发比 Eclipse 的卡,其实这也是他实现的方式造成。

但是 gradle 项目却提供了很多eclipse 不方便提供的功能。比如渠道模式

比如渠道模式:

在build.gradle 中有这样的设定 productFlavors 这样的设定,当改设定存在,则 main 主代码渠道不在进行打包,全部依赖渠道进行编译安装调试

看到我的 productFlavors 中定义了两个版本,一个是线上测试餐饮版,一个是线上测试大众版。你看了,可能举得这么定义没什么用,你看到大括号里面了么?? applicationID,恩,没错,这就是可以重新定义他的包名,在这括号里面能够重新定义defaultConfig里面的所有配置。每个渠道的版本号都能单独维护。不需要你写ant脚本去替换。而且每个渠道也是同时可以编译 debug 和 release 版本

再来看下图:

记得在目录详解的目录上,设定的是 main 渠道的目录,恩,没错,现在我设定的是渠道的目录。这个怎么说?还记得我设定主目录的设定代码么?

sourceSets {
main.setRoot('src/main')
main {
manifest.srcFile '[mainRoot]/AndroidManifest.xml'
java.srcDirs = ['[mainRoot]/java']
resources.srcDirs = ['[mainRoot]/java']
aidl.srcDirs = ['[mainRoot]/aidl']
res.srcDirs = ['[mainRoot]/res']
assets.srcDirs = ['[mainRoot]/assets']
jni.srcDirs=['[mainRoot]/jni']
jniLibs.srcDirs = ['[mainRoot]/jniLibs']
}

没错,你看到的,所有android相关的文件,都在某个root下面。

那么,我们渠道上面设置的的路径也是基于如此路径进行文件分类的。

恩,没错,设定了渠道的内容,编译渠道的时候,不同的渠道就会依据主项目,然后替换自己的内容。 比如上图的String,你需要替换的只要写入你需要替换的String name,这么value的值就会在这个渠道就会替换过来。包括drawable等二进制文件,他会进行替换操作,比如说,你给应用宝打包的应用启动欢迎页是应用宝的,给其他应用商城的是其他图片,就可完全放置在渠道文件夹内。

如何检查是否合并?检查 build 文件内的合并内容,具体的不细说,你应该能找到,比如某个渠道替换的文件,找到那个渠道相应的文件查看即可。如果时Value的值,那就查看value文件内对应的name是否已经变更成功。

说到这个,不得不提,你有时候双击报错信息,打开了某个文件,或者某个图片(.9图较多),想对其进行修改,你发现它是只读状态,不可修改,恩,没错,这个编译文件经过 gradle 拷贝到build 相应渠道目录下才开始进行编译,在那个目录下的文件都是只读状态,并非你的源代码文件。你可以根据提示信息找到你自己的源文件进行修改。

你可能会问,这么多渠道包,那我要调试,究竟默认使用哪个渠道呢?看下图:

恩,你没看错,在项目下面,有个选择编译版本的地方。。这样,你想调试那个渠道的版本都可以轻松进行了。

提速编译

gradle 在编译时候有些东西跟java虚拟机相关,记得一开头的项目文件 gradle.properties 么?这个是设定 gradle 在运行时的编译环境。

在渠道编译的时候,默认情况下,一个渠道会启用一个java 虚拟机进行编译,在java 虚拟机启动,关闭的过程是非常耗时的,gradle 提供了守护进程的模式进行编译,从头到尾就使用一个java 虚拟机(jvm)

至于什么是守护进程模式,资料比较多,我就不解析了,可看这里这里

同时,根据你自己的电脑内存,你还可以定义虚拟机的内存数大小,这个其实会关乎你电脑卡不卡的问题,电脑内存太小,编译虚拟机内存太多,也许你切换个环境都会觉得举步维艰吧。

很多教程,都写编译打包版本,使用命令

./gradlew
build

可是,都不会告诉你,更好的提高效率。官方提供release 版本与debug版本的区别编译

一般我们要编译所有渠道的 release版本,会使用如下命令:

./gradlew assembleRelease
#or
./gradlew aR

你肯定会问,如果我基于一个稳定版本,新增一个渠道,我只想打包一个渠道,怎么办?之行下面的命令看看

./gradlew
task

这会列表所有 gradle task。task的概念我就不解释了,很多gradle教程已经说了。

我只要打包 onlinetestcatering 渠道,只要之行这样的命令就可以了。

./gradlew
task
assembleOnlinetestcateringRelease

结尾

以上内容,就是我针对 IDEA 并使用 Gradle 构建的一些深入理解与提升的内容。关于 NDK 代码编译,以及代码混淆配置,打包 key 的设置,很多教程都已经解答过了,我也就不在说明了。

   
 订阅
  捐助
相关文章

为什么要做持续部署?
剖析“持续交付”:五个核心实践
集成与构建指南
持续集成工具的选择-装载
相关文档

持续集成介绍
使用Hudson持续集成
持续集成之-依赖管理
IPD集成产品开发管理
相关课程

配置管理、日构建与持续集成
软件架构设计方法、案例与实践
单元测试、重构及持续集成
基于Android的单元、性能测试
 

集成与构建指南
项目管理:Maven让事情变得简单
持续集成工具hudson
持续集成
Maven权威指南
程序集(UML中的包)之间循环
更多...   


产品发布管理
配置管理方法、实践、工具
多层次集成配置管理
使用CC与CQ进行项目实践
CVS与配置管理
Subversion管理员

相关咨询服务
SCM启动咨询
SCM流程规范咨询
SCM评估性咨询


海航股份 重构及持续集成
电研华源 设计原理、建模与重构
软件配置管理日构建及持续集成
单元测试、重构及持续集成
中国软件研发中心 单元测试与重构
单元测试、重构和持续集成实践
罗克韦尔 C++单元测试+重构+Gtest
更多...   
 
 
 
 
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号