技术标签: gradle groovy productFlavor android buildtypes
自从用Android Studio开发以来,一直不是很懂gradle是干嘛用的,一旦出现Gradle相关的什么错误(比如包下不来:cannot resolve dependencies........),都不知道怎么解决。
恰逢昨天上CSDN上看文章的时候,看到一位大神分享的文章:深入理解Android之Gradle。感觉自己懂了很多,现在就来分享下自己的心得。该文章的主要知识点来自以下几个网站,还有个人的一些经验分享。前面两篇文章比较重要。
深入理解Android之Gradle
Android Plugin For Gradle
Android Plugin For Gradle Release Notes
言归正传,最近听到很多名词,例如Groovy,Gradle,Ant,Maven,先来解释下都是干嘛的:
Groovy:一种语言,就像java、c++,它是一种基于JVM的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Jaa 代v码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy 可以使用其他 Java 语言编写的库。执行该语言的脚本时,Groovy会先将其编译成Java类字节码,然后通过Jvm来执行这个Java类。
Gradle:是以 Groovy 语言为基础,面向Java应用为主。基于DSL(领域特定语言)语法的自动化构建工具,用在Android中就是用来构建工程的工具,可以build等等。
Ant :原来用在Eclipse中打包的工具,现在已经被Gradle代替。
Maven :是一个解决包依赖的管理系统,在Android中app project经常需要依赖一些外部或者本地的包。
对于Groovy,这里不再多做解释,如何安装Groovy请自行上网查找,如果想要了解Groovy的语法,请看深入理解Android之Gradle这篇文章中已经讲述。建议大家先看下,因为Gradle是基于Groovy的,要不然后面讲到Gradle的时候,会看不懂。
现在讲Gradle,下面一段话是android developers上对gradle的一段描述
The Android build system consists of an Android plugin for Gradle.Gradle is an advanced build toolkit that manages dependencies and allows you to define custom build logic. Android Studio uses a Gradle wrapper to fully integrate the Android plugin for Gradle. The Android plugin for Gradle also runs independent of Android Studio. This means that you can build your Android apps from within Android Studio and from the command line on your machine or on machines where Android Studio is not installed (such as continuous integration servers).
The output of the build is the same whether you are building a project from the command line, on a remote machine, or using Android Studio.
这里说到Gradle是一个管理依赖并允许开发者自定义构建逻辑的高级构建工具。这段话中还有另外一个概念就是Gradle Plugin,它是独立于Android Studio,可以通过各种Plugin插件扩展功能以适应各种构建任务,这就意味着你可以在其他machine上build你的App。
那都有哪些Plugin呢?在一个Android Project中有多个module,
如果Module是application,则apply plugin:'com.android.application'(原来是apply plugin:'android',这是旧的写法)
如果Module是library,则apply plugin:'com.android.library'
当然还有其他的plugin,这里不再赘述。
所以你要分清楚gradle和gradle plugin,不要老虎老鼠傻傻分不清楚。在project目录下的build.gradle中声明了使用哪个版本的gradle plugin
在project目录下的gradle/wrapper/gradle-wrapper.properties中说明了使用哪个版本的gradle
在build.gradle中说明了如何去build。当我们新建一个project的时候,这时候只有一个app模块,我们看下project和app下的build.gradle。这里要注意的是,project下的build.gradle是对全局的配置,工程下的每个module都会有一个build.gradle,来自定义各自模块的build逻辑。
Android Studio projects contain a top-level project Gradle build file that allows you to add the configuration options common to all application modules in the project. Each application module also has its own build.gradle file for build settings specific to that module.
project下:
app下:
再来介绍project下的一个文件setting.gradle,该文件记录了在该project下所有的module,目前只有这一个app,所以只有该模块。如果你添加模块,这里会自动添加。
Android中都有哪些module呢?
buildTypes {
release {
。。。。
}
debug {
。。。。
}
mockType{
。。。。
}
}
每次更改build.gradle的内容,会要求你sync,sync完你发现buildVariant中的内容也改变了
接下来在介绍ProductFlavor,比如说现在你有个游戏应用,分为free和paid,在代码中这么加即可
buildTypes {
release {
。。。。
}
debug {
。。。。
}
}
productFlavors{
free {
。。。。
}
paid {
。。。。
}
}
这时你再sync下,看buildVariant,发现productFlavor和buildTypes进行两两组合了。结果是2*2=4种
//下面这句话很重要,组合的方式是按照这个顺序来的,如果是"type","cpu",则组合出来的是free-x86-debug
flavorDimensions "CPU","type"
productFlavors {
x86 {
dimension='CPU'
}
arm {
dimension='CPU'
}
free {
dimension='type'
}
paid {
dimension='type'
}
}
再sync下,看buildVariant
buildTypes {
release {
//主要用来控制是否运行混淆的,还不是很懂,继续查找
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//在BuildConfig.java中添加字段
buildConfigField("String", "url", "${releaseUrl}");
//指定签名使用哪个keystore
signingConfig signingConfigs.config
}
debug {
buildConfigField("String", "url", "${debugUrl}");
}
}
在project目录下的gradle.properties中加入如下代码
现在要求升级,比如说你的app要求比较高,在不同CPU下有不同的版本,分为x86和arm,你希望的结果是有八种模式,分别为
x86-free-debug、x86-free-release
x86-paid-debug、x86-paid-release
arm-free-debug、arm-free-release
arm-paid-debug、arm-paid-release
这就需要multi-dimensions product flavor
代码如下
现在理解了productFlavor这东西了吧。
接下来讲下刚才在buildTypes中release让大家忽略的东西。
平时写代码的时候,在app发布之前,我们会让app访问本地服务器,这是一个url,并且记录为全局的。当发布的时候,需要将url改成部署的服务器的地址。假如现在这个url记录在Config.java中,如果每次发布打包时都去检测该url是否正确的话太麻烦了,万一哪天忘记了呢?这里提供一个解决办法。
releaseUrl="helloworld--release"
debugUrl="helloworld--debug"
这时你再sync下,看该目录下的结构和文件
所以应用程序中的url可以从buildConfig.java中取BuildConfig.url即可。
Dependency:
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.xx"
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
dev{
....
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
}
}
}
dependencies {
// compile project(':sdk')
debugCompile project(path: ':sdk', configuration: 'debug')
releaseCompile project(path: ':sdk', configuration: 'release')
devCompile project(path: ':sdk', configuration: 'dev')
}
如果是添加了flavor:
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.xx"
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
productFlavors{
flavor1{
....
}
flavor2{
....
}
}
}
dependencies {
// compile project(':sdk')
flavor1Compile project(path: ':sdk', configuration: 'debug')
flavor2Compile project(path: ':sdk', configuration: 'release')
}
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.xx"
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
}
}
productFlavors{
online{
}
offline{
}
}
}
configurations{
onlineDebugCompile
offlineDebugCompile
onlineReleaseCompile
offlineReleaseCompile
}
dependencies {
onlineDebugCompile project(path: ':sdk', configuration: 'onlineDebug')
offlineDebugCompile project(path: ':sdk', configuration: 'offlineDebug')
onlineReleaseCompile project(path: ':sdk', configuration: 'onlineRelease')
offlineReleaseCompile project(path: ':sdk', configuration: 'offlineRelease')
}
讲完这部分,将gradle中的tasks,看下面这张图
Gradle基于Groovy,Groovy又基于Java。所以,Gradle执行的时候和Groovy一样,会把脚本转换成Java对象。Gradle主要有三种对象,这三种对象和三种不同的脚本文件对应,在gradle执行的时候,会将脚本转换成对应的对端:
你可以选择离线下载该jar包,然后根据错误提示信息将jar包放在相应的目录下。讲个例子
你可以先上网下载那个文件,然后放在C:\Users\本计算机的名字\.m2\repository + org\jacoco\org.jacoco.agent\0.7.1.201405082137\目录下
如果没有该目录,自己创建
今天收到PhysicsEditor作者发过来的license key,所以顺便把PhysicsEditor也尝试了一下。主要是尝试将PhysicsEditor与cocos2dx,box2d结合开发的一些步骤。之前大概网络检索了一下,知道PhysicsEditor的功能其实很简单。一句话就是给图片的边缘定位,并且指定图片对齐(重心?)位置,然后导出成plist文件。用来快速给box2d提供图片...
js中定时器有两种,一个是循环执行setInterval,另一个是定时执行setTimeout一、循环执行(setInterval)顾名思义,循环执行就是设置一个时间间隔,每过一段时间都会执行一次这个方法,直到这个定时器被销毁掉用法是setInterval(“方法名或方法”,“延时”), 第一个参数为方法名或者方法,注意为方法名的时候不要加括号,第二个参数为时间间隔常见方法。在data中声明一个变量,定时器绑定到变量中,然后在beforeDestory中销毁这个定时器举个例子:方案一:首先我在_vue 计时器 两种方法
Spring4 @EnableWebMvc 纯注解启动一、WebConfig想要以Java形式定制默认的配置,你可以简单的实现WebMvcConfigurer接口,或者继承WebMvcConfigurerAdapter并重写需要的方法@Configuration表示这是Java配置类;@EnableWebMvc注解用于启动Spring MVC特性。package com.my;_@enablewebmvc的pom
最近项目中要实现ViewPage实现无缝循环滑动,就是类似淘宝上的广告
#include<stdio.h>int main(){ int i,j,k,sum,t; int a[1000];/*定义一个足够大的数组*/ for(i=2;i<1000;i++){ for(t=1,sum=0,j=1;j<i;j++){ /*判断j是不是因子*/ if(i%j==0){ sum+=j; /*把因子存到数组中*/ a[t++]=j; } } if(i==sum){ /*输出完数*/ ._int a【1000】
简介什么是MyBatis持久化持久层为什么需要MyBatis第一个MyBatis程序搭建环境搭建数据库创建一个模块编写代码测试CRUDnamespaceselectinsertupdatedelete分析错误万能Map思考题模糊查询怎么写配置解析核心配置文件环境配置属性类型别名(typeAliases)设置其他配置映射器(mappers)生命._mybatis bishi ti
嗨im仍然是新手在android编程。我想知道如何在android代码中读取像“/home/emulator/0/blabla/file.txt/”这样的文件路径。我需要知道如何读取文件路径,因为我必须从应用程序访问android上的特定文件。并且路径已经在代码中定义了,所以用户只会得到读数的输出。阅读文件路径android studiopublic void naivebayes() throw..._android studio读取同一路径下的文件
京东一面凉经object的方法,7大方法synchronized方法讲解synchronized方法实现原理volatile关键字的原理锁的分类偏向锁讲解NoClassDefFoundError和ClassNotFoundException的区别追问,ClassNotFoundException是不是只发生在编译时,运行时可不可以类加载机 制redis过期策略及内存淘汰机制mysql的索引种类4种Innodb和myIsam的区别Innodb的索引结构B+树的优缺点海量数据的索
Androidso库 异常保错: is not accessible for the namespace "classloader-namespace" 具体 so是我自己项目独有的,但是报错应该不是个例,而且下面的错误偶发出现。java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib/libserial_port.so" needed or dlopened by "/system/lib/libnativelo..._dlopen failed: library "/system/lib64/libserial_port.so" needed
最近经常有很多朋友问我想要入行软件测试,但是都不知道该怎么学。这里详细的给大家说下,对于0基础的朋友,应该怎么去学习软件测试。_软件测试学多久找到工作
差分约束系统解决区间选点问题。题目描述:给定一个数轴上的 n 个区间,要求在数轴上选取最少的点使得第 i 个区间 [ai, bi] 里至少有 ci 个点使用差分约束系统的解法解决这道题input:输入第一行一个整数 n 表示区间的个数,接下来的 n 行,每一行两个用空格隔开的整数 a,b 表示区间的左右端点。1 <= n <= 50000, 0 <= ai &..._程序设计思维与实践拿数问题 ii
蓝桥杯: 区间最大和问题描述 给定一段长度为N的整数序列A,请从中选出一段连续的子序列(可以为0)使得这段的总和最大。输入格式 第一行一个整数N表示序列的长度 第二行N个整数Ai表示序列的第i个元素输出格式 一个整数表示选出的最大的和样例输入43 -10 1 1样例输出3import java.util.Scanner;public class Main { public static void main(String[] args) { Sca_区间最大和