以下内容是本人使用gradle的一些心得,主要是关于android项目的build.gradle文件的配置说明和自己的一些使用技巧,好了,废话不多说,我们开始吧!
build.gradle介绍:
- 工程类型声明:
表明这个工程是一个应用
apply plugin: 'com.android.application'
表明这个工程是一个库工程
apply plugin: 'com.android.library'
创建完项目之后想要修改工程属性可以通过这种方法(刚开始的时候我还找了好久,好蠢。。。)
- 工程配置说明: android项目的基础配置
android {
//这两个是常规设置,忽略打包是的一些错误和异常
dexOptions {
incremental true
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
signingConfigs {
//这里可以配置apk包的签名文件,可以配置多个
signing_1 {
keyAlias 'test'
keyPassword 'test'
storeFile file('../test.keystore')
storePassword 'test'
}
signing_2 {
keyAlias 'test'
keyPassword 'test'
storeFile file('../test.keystore')
storePassword 'test'
}
...
}
defaultConfig {
//默认的包名
applicationId 'com.test'
minSdkVersion 15
targetSdkVersion 23
/
//multiDexEnabled可以解决java函数超过65536的溢出问题
multiDexEnabled = true
//默认的签名文件
signingConfig signingConfigs.signing_1
}
//资源配置
sourceSets {
//默认的资源路径
main {
java.srcDir "src/main/java"
res.srcDir "src/main/res"
jniLibs.srcDir "src/main/jniLibs"
manifest.srcFile "src/main/AndroidManifest.xml"
}
}
buildTypes {
release {
//是否开启混淆,因为我们的项目引用的sdk实在太多了,添加混淆比较麻烦,这里就偷个懒把它关了
minifyEnabled false
//打包的时候会自动去除未使用的资源
shrinkResources true
//设置release或者debug签名
signingConfig signingConfigs.signing_1
}
debug {
//我的这里也设置为了release签名是为了debug的时候不用再把release包删掉了,而且还可以使用release包的游戏缓存
signingConfig signingConfigs.signing_1
}
}
}
- productFlavors多渠道配置神器
android {
//这个就是大名鼎鼎的多渠道打包神器
productFlavors {
wandoujia {
//定义各个渠道包的包名
applicationId "com.test.wandoujia"
//所有在androidmainifest文件中配置的属性都可以在这里填充
manifestPlaceholders = [
talkingdata_channel : "wandoujia"
]
}
baidu {
applicationId "com.test.baidu"
manifestPlaceholders = [
talkingdata_channel : "baidu"
]
}
...
}
}
相应的 Androidmanifest文件的写法如下:
<meta-data android:name="TK_Channel" android:value="${talkingdata_channel}"/>
可以在Androidmanifest文件中配置的属性都可以在manifestPlaceholders里面进行相应的替换 假如各个渠道包的icon,名称(res文件夹下的资源)不同时怎么处理呢,这个也好办:
android {
sourceSets {
wandoujia {
res.srcDir "src/main/res_wdj"
}
baidu {
res.srcDir "src/main/res_bd"
}
}
}
- 工程依赖配置
//引用aar类型的sdk需要额外添加这一段代码
repositories {
flatDir {
//aar文件路径
dirs 'libs'
}
}
dependencies {
//引用库工程
compile project(':bugly')
//引用jar文件
compile files('libs/fastjson.jar')
//或者引用一个目录下的所有jar文件
compile fileTree(dir: 'libs', include: ['*.jar'])
//引用aar文件
compile(name: 'play-services-games-9.0.2', ext: 'aar')
}
注意:上述的配置会将dependencies中加入的sdk打入到所有渠道版本的apk中,假如你只是需要在其中的某些渠道加入sdk的话可以将“compile”修改为在productFlavors配置的渠道名+“Compile”如: 只有豌豆荚需要打入bugly的sdk则可以写成
dependencies {
wandoujiaCompile project(':bugly')
}
优化打包配置
下面是我自己的项目的一些大致配置,另外写了一个json文件用来配置各个包的属性,也比较直观 package.json内容如下:
{
"com.test.wandoujia": {
"name": "basicflavor",
"assetDir": "assets_wandoujia",
"resDir": "res_wandoujia",
"f_id": "@string/f_id_wandoujia",
"talkingdata_channel": "wandoujia"
},
"com.test.baidu": {
"name": "fullflavor",
"assetDir": "assets_baidu",
"resDir": "res_baidu",
"f_id": "@string/f_id_baidu",
"talkingdata_channel": "baidu"
}
}
build.gradl文件中的解析代码如下(省略了无关代码)
import org.json.JSONObject
android {
def jsonfile = new File(getProjectDir().getPath() + "/../package.json")
if (jsonfile.exists()) {
def jsonObject = new JSONObject(jsonfile.text)
if (jsonObject != null) {
jsonObject.keys().toList().each { key ->
def flavor = jsonObject.getJSONObject(key)
def name = flavor.getString("name")
def assetDir = flavor.getString("assetDir")
def resDir = flavor.getString("resDir")
def facebook_id = flavor.getString("f_id")
def talkingdata = flavor.getString("talkingdata_channel")
sourceSets {
"${name}" {
res.srcDir "src/main/" + resDir
assets.srcDir "src/main/" + assetDir
}
}
productFlavors {
"${name}" {
applicationId "${key}"
manifestPlaceholders = [package_name : applicationId,
facebook_id : facebook_id,
talkingdata_channel : talkingdata,
]
if (name.toLowerCase().contains("wandoujia") == false){
def compileName = name+"Compile"
dependencies {
"${compileName}" project(':bugly')
}
}
}
}
}
}
}
}
这样的话增加渠道包就只需要在package.json文件中增加一个条目就好了。 之后就调用
gradle assembleRelease
命令就可以打包所有的release渠道包,由于目录比较深(build/outputs/apk),在打包任务结束之后添加了一个拷贝操作,将所有的release包拷贝到apk的统一存放路径中:
assembleRelease.doLast {
def time = new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
def dir = new File(getProjectDir().getPath() + "/build/outputs/apk/")
def files = dir.listFiles()
files.each { File file ->
def fileName = file.name
if (fileName.endsWith("release.apk")) {
//这里拷贝apk文件
copy {
from "./build/outputs/apk/" + fileName
into "../../outputs/"
rename {
fileName = fileName - "release.apk" + "${time}.apk"
}
}
}
}
}
到这里就差不多结束了,想吐槽的就在下面留言吧!