可参照:
(1)http://blog.chinaunix.net/uid-20771867-id-5106723.html
(2)http://www.th7.cn/Program/Android/201501/380594.shtml
//—————————————————————————————-
(a)
apply plugin: 'com.android.application'
apply plugin: 'com.droidtitan.lintcleaner'
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
def vCode() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
android {
compileSdkVersion 21
buildToolsVersion "22.0.1"
signingConfigs {
apply plugin: 'signing'
release {
storeFile file("../androidkey.keystore")
storePassword "yourpassword"
keyAlias "youralias"
keyPassword "yourkey"
}
}
defaultConfig {
applicationId "your package name"
minSdkVersion 15
targetSdkVersion 21
versionCode Integer.valueOf(vCode())
versionName "2.1.10"
}
//多个版本的打包配置
productFlavors {
Version1{
applicationId "your package name1"
manifestPlaceholders = [GAO_DE_KEY: "your gaode key1", UMENG_KEY: "your umeng key1"]
}
Version2 {
applicationId "your package name2"
manifestPlaceholders = [GAO_DE_KEY: "your gaode key2", UMENG_KEY: "your umeng key2"]
}
}
buildTypes {
release {
signingConfig signingConfigs.release
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//将release版本的包名重命名,加上版本及日期
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('release.apk')) {
def fileName = "${variant.productFlavors[0].name}_V${defaultConfig.versionName}_${releaseTime()}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
debug {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
repositories {
maven { url "https://jitpack.io" }
}
//用来清除无用资源的插件,详见https://github.com/marcoRS/lint-cleaner-plugin
lintCleaner {
// Exclude specific files
exclude = ['umeng*.png', '*.xml']
// Ability to ignore all resource files. False by default.
ignoreResFiles = true
}
//将打包后的文件复制到build目录下,这样就不用深入到apk目录,同时还看不到unaligned的apk了
task copyTask(type: Copy) {
from 'build/outputs/apk/'
into 'build/'
exclude '*-unaligned.apk'
}
task bd(dependsOn: ['assembleDebug', 'assembleRelease', 'copyTask']){
copyTask.mustRunAfter assembleRelease
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
// compile 'com.squareup.retrofit:retrofit:1.9.0'
// compile 'com.squareup.okhttp:okhttp:2.3.0'
// compile 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
// compile 'com.facebook.stetho:stetho:1.1.1'
// compile 'com.facebook.stetho:stetho-okhttp:1.1.1'
// compile 'io.reactivex:rxandroid:0.24.0'
// compile 'com.jakewharton:butterknife:6.1.0'
compile 'com.facebook.fresco:fresco:0.5.2+'
compile 'me.imid.swipebacklayout.lib:library:1.0.0'
compile 'se.emilsjolander:stickylistheaders:2.6.0'
compile 'de.greenrobot:eventbus:2.4.0'
compile 'com.github.PhilJay:MPAndroidChart:v2.0.9'
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.android.support:support-v13:22.2.0'
compile project(':carShopSyncLib')
}
//—————————————————————————————-
(b)
项目切换到Android Studio有一段时间了,来聊聊多渠道打包的做法。
1.在productFlavors添加你需要的所有渠道
android {
productFlavors { //在这里添加你所有需要打包的渠道
dev {}
google {}
myapp {}
xiaomi {}
app360 {}
wandoujia {}
}
//添加如下代码
productFlavors.all { flavors->
flavors.manifestPlaceholders=[CHANNEL_VALUE:name]
}
}
同时修改androidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="cn.op.zdf"
android:versionCode="25"
android:versionName="3.1.2">
<application
android:name=".myApplication">
<-- 在manifest中添加如下代码--->
<meta-data
android:name="UMENG_CHANNEL"
android:value="${CHANNEL_VALUE}"/>
</application>
</manifest>
OK,在命令行运行gradle build,大功告成。你可以去喝杯茶了。
2.如何给apk重命名
恩,发布产品的时候我们需要如下的命名规则
release版本的命名规则如下:
产品名称-版本号-渠道号-sign-42.apk
在build.gradle中添加如下代码
//获取时间戳
def getDate() {
def date = new Date()
def formattedDate = date.format('yyyyMMddHHmm')
return formattedDate
}
//从androidManifest.xml中获取版本号
def getVersionNameFromManifest(){
def manifestParser = new com.android.builder.core.DefaultManifestParser()
return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
}
android{
//修改生成的apk名字
applicationVariants.all{ variant->
variant.outputs.each { output->
def oldFile = output.outputFile
def newName = '';
if(variant.buildType.name.equals('release')){
// println(variant.productFlavors[0].name)
def releaseApkName = 'yjf-android-v' + getVersionNameFromManifest() + '-' + variant.productFlavors[0].name + '-sign-42.apk'
output.outputFile = new File(oldFile.parent, releaseApkName)
}
if(variant.buildType.name.equals('beta')){
newName = oldFile.name.replace(".apk", "-v" + getVersionNameFromManifest() + "-build" + getDate() + ".apk")
output.outputFile = new File(oldFile.parent, newName)
}
if(variant.buildType.name.equals('debug')){
}
}
}
}
哦,怎么取得版本号?怎么取得渠道号?怎么判断是不是release版本?上面的代码里面都有。
我的项目是从eclipse中迁移过来的,所以我是从manifest文件中读取的版本号,就是上面的那个函数 getVersionNameFromManifest()
如果你的版本号定义在build.gradle中,那defaultConfig.versionName就是你的版本号。
//———————————————————————————-
下面是我自己的命名:
apply plugin: 'com.android.application'
//apply plugin: 'com.android.databinding'
def appName() {
return "APP_NAME"
}
def releaseTime() {
return new Date().format("yyyyMMddHHmm", TimeZone.getDefault())
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "xxxx.xxxx.xxxx.xxxxx"
minSdkVersion 15
targetSdkVersion 19
versionCode 9
versionName "1.0.14"
// Enabling multidex support.
// dex突破65535的限制
multiDexEnabled true
}
signingConfigs {
debug {
storeFile file('tools/signature.keystore')
storePassword SIGNING_STOREPASSWORD
keyAlias SIGNING_KEYALIAS
keyPassword SIGNING_KEYPASSWORD
}
release {
storeFile file('tools/signature.keystore')
storePassword SIGNING_STOREPASSWORD
keyAlias SIGNING_KEYALIAS
keyPassword SIGNING_KEYPASSWORD
}
}
buildTypes {
debug {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
//加载默认混淆配置文件 progudard-android.txt在sdk目录里面,不用管,proguard.cfg是我们自己配的混淆文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//签名
signingConfig signingConfigs.debug
//将release版本的包名重命名,加上版本及日期,连接真机调试的时候请注释掉
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('debug.apk')) {
//def fileName = "${variant.productFlavors[0].name}_V${defaultConfig.versionName}_${releaseTime()}.apk"
def productFlavorsName = variant.productFlavors[0].name;
def fileName = "${appName()}.V${defaultConfig.versionName}.${releaseTime()}.alpha."+productFlavorsName+".apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
release {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//混淆
minifyEnabled true
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
//加载默认混淆配置文件 progudard-android.txt在sdk目录里面,不用管,proguard.cfg是我们自己配的混淆文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//签名
signingConfig signingConfigs.release
//
//将release版本的包名重命名,加上版本及日期
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('release.apk')) {
//def fileName = "${variant.productFlavors[0].name}_V${defaultConfig.versionName}_${releaseTime()}.apk"
def productFlavorsName = variant.productFlavors[0].name;
def fileName = "${appName()}.V${defaultConfig.versionName}.${releaseTime()}.release."+productFlavorsName+".apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
sourceSets {
main {
//manifest.srcFile 'AndroidManifest.xml'
//java.srcDirs = ['src']
//resources.srcDirs = ['resources']
//res.srcDirs = ['res']
//assets.srcDirs = ['assets']
//aidl.srcDirs = ['src']
//renderscript.srcDirs = ['src']
jniLibs.srcDirs = ['libs']
}
androidTest.setRoot('tests')
}
allprojects {
repositories {
jcenter()
mavenCentral();
}
}
lintOptions {
abortOnError false
//disable 'InvalidPackage'
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
}
// 在生成的apk文件,修改下命名而已
// applicationVariants.all { variant ->
// variant.outputs.each { output ->
// def outputFile = output.outputFile
// if (outputFile != null && outputFile.name.endsWith('.apk')) {
// //def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
// def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
// output.outputFile = new File(outputFile.parent, fileName)
// }
// }
// }
productFlavors {
yijiajiao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
yingyongbao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "XXXX"]
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.1'
compile '......'
}
生成的apk名字是:
APP_NAME.V1.0.14.201510300950.alpha.yijiajiao.apk
APP_NAME.V1.0.14.201510300950.alpha.yingyongbao.apk
APP_NAME.V1.0.14.201510300950.alpha.xiaomi.apk
APP_NAME.V1.0.14.201510300950.alpha.wandoujia.apk