Gradle编译打包小结

原文地址
http://blog.csdn.net/byhook/article/details/51746825

以前用Eclipse打包,比较笨,右键导出签名
现在一直是用的Android Studio来开发
用Gradle编译打包非常方便
笔者整理的平时编译打包的配置,记录一下,避免遗忘
1.自动签名
可以直接写在build.gradle里,如:

signingConfigs {
        develop {
            storeFile '/xxxxxx/xxx.jks'
            keyAlias 'xxxxxx'
            keyPassword 'xxxxxx'
            storePassword 'xxxxxx'
        }
    }

笔者习惯写在配置文件里,然后加入ignore方便后续更改


/**
 * 读取签名
 * @return
 */
def getSignProperty() {
    def Properties buildProperties = new Properties()
    buildProperties.load(new FileInputStream(file('../config/sign.properties')))
    return buildProperties
}

签名配置sign.properties

STORE_PASSWORD=xxxxxx
KEY_PASSWORD=xxxxxx
KEY_ALIAS=xxxxxx
STORE_FILE=xxxxxx.jks

2.同时打出不同环境的包
正常情况下一个项目可能同时有测试环境和正式环境
如果每次打包都去改配置是非常繁琐的,而且容易出错
建议在配置文件里直接添加配置

productFlavors {
        buildDevelop {
            buildConfigField "boolean", "MODEL_DEV", "true"
            versionName = mVersionName
        }
        buildRelease {
            buildConfigField "boolean", "MODEL_DEV", "false"
            versionName = mVersionName
        }
    }

如上所述,打包的时候会同时打出两个不同的包,一个是测试环境一个是正式环境

3.输出日志
记录打包时候的时间,版本号以及Git提交的版本等等,方便日后审查

/**
 * 输出日志
 */
def buildLog(String output,String vName,String vCode) {
    File outputFile = new File(output)
    if(!outputFile.exists())
        outputFile.mkdirs()
    FileWriter fw = new FileWriter(output + File.separator + "log.txt")
    StringBuilder builder = new StringBuilder();
    builder.append("[构建时间]=" + buildTime("yy-MM-dd HH:mm"))
    builder.append("\r\n")
    builder.append("[版本编号]=" + vCode)
    builder.append("\r\n")
    builder.append("[版本名称]=" + vName)
    builder.append("\r\n")
    builder.append("[提交记录]=" + getGitVersion())
    fw.write(builder.toString())
    fw.flush();
    fw.close();
}

相关的函数

/**
 * 读取Git日志
 * @return
 */
def getGitVersion() {
    return 'git rev-parse --short HEAD'.execute().text.trim()
}

/**
 * 构建时间
 * @return
 */
def buildTime(String time) {
    def date = new Date()
    def formattedDate = date.format(time)
    return formattedDate
}

4.编译构建完成之后最好备份一下mapping文件

build {
    doLast {
        //记录日志
        buildLog(mOutputs,mVersionName,mVersionProps['VERSION_CODE'])
        //复制文件
        copy {
            from "$buildDir/outputs/mapping"
            into mOutputs
        }
    }
}

最后的全局配置文件

apply plugin: 'com.android.application'

/**
 * 读取版本配置
 */
def Properties mVersionProps = getVersionProperty();

/**
 * 读取版本名
 */
def mVersionName = buildRelease() ? mVersionProps['VERSION_NAME'] : "build_" + buildTime('yyMMdd')

/**
 * 输出目录
 */
def mOutputs = "$rootDir/outputs/build_" + buildTime('yyMMdd')

android {

    signingConfigs {
        develop {
            def Properties buildSignProps = getSignProperty()
            storeFile file(buildSignProps['STORE_FILE'])
            keyAlias buildSignProps['KEY_ALIAS']
            keyPassword buildSignProps['KEY_PASSWORD']
            storePassword buildSignProps['STORE_PASSWORD']
        }
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            buildConfigField "boolean", "MODEL_DEV", "true"
        }
        release {
            minifyEnabled true
            buildConfigField "boolean", "MODEL_DEV", "false"
            signingConfig signingConfigs.develop

            zipAlignEnabled true
            //去掉无用资源
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    //读取版本配置
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    defaultConfig {
        applicationId "cn.byhook.main"
        minSdkVersion 9
        targetSdkVersion 23
        versionCode Integer.valueOf(mVersionProps['VERSION_CODE'])
        versionName = mVersionName
    }

    dexOptions {
        javaMaxHeapSize "4g"
    }

    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    productFlavors {
        /*_$ { variant.productFlavors.get(0).name }
        $ { variant.buildType.name }*/
        buildDebug {
            buildConfigField "boolean", "MODEL_DEV", "true"
            versionName = "Local Version"
        }
        buildDevelop {
            buildConfigField "boolean", "MODEL_DEV", "true"
            versionName = mVersionName
        }
        buildRelease {
            buildConfigField "boolean", "MODEL_DEV", "false"
            versionName = mVersionName
        }
    }


    if (buildRelease()) {
        android.variantFilter { variant ->
            if (variant.buildType.name.equals('release')) {
                variant.getFlavors().each() { flavor ->
                    if (flavor.name.equals('buildDebug')) {
                        variant.setIgnore(true);
                    }
                }
            }
        }
    }

    //输出文件配置
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                if ("release".equals(variant.buildType.name)) {
                    if ("buildDevelop".equals(variant.productFlavors.get(0).name)) {
                        output.outputFile = new File(
                                mOutputs,
                                "Main_${buildTime("yyMMddHHmm")}_dev.apk")
                    } else if ("buildRelease".equals(variant.productFlavors.get(0).name)) {
                        output.outputFile = new File(
                                mOutputs,
                                "Main_${buildTime("yyMMddHHmm")}.apk")
                    }
                } else {
                    output.outputFile = new File(
                            outputFile.parent,
                            "app-debug.apk")
                }
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    testCompile 'org.robolectric:robolectric:3.1'
    compile project(':Exlibrary')
}

/********************************************************************
 * 打包脚本
 ********************************************************************/

/**
 * 构建版本
 * @return
 */
def getVersionProperty() {
    def Properties buildProps = new Properties()
    buildProps.load(new FileInputStream(file('../config/version.properties')))
    return buildProps;
}

/**
 * 读取签名
 * @return
 */
def getSignProperty() {
    def Properties buildProperties = new Properties()
    buildProperties.load(new FileInputStream(file('../config/sign.properties')))
    return buildProperties
}

/**
 * 构建时间
 * @return
 */
def buildTime(String time) {
    def date = new Date()
    def formattedDate = date.format(time)
    return formattedDate
}

/**
 * 是否发布
 * 发布为真
 * 版本号自增
 * @return
 */
def buildRelease() {
    return false
}

/**
 * 读取Git日志
 * @return
 */
def getGitVersion() {
    return 'git rev-parse --short HEAD'.execute().text.trim()
}

/**
 * 输出日志
 */
def buildLog(String output,String vName,String vCode) {
    File outputFile = new File(output)
    if(!outputFile.exists())
        outputFile.mkdirs()
    FileWriter fw = new FileWriter(output + File.separator + "log.txt")
    StringBuilder builder = new StringBuilder();
    builder.append("[构建时间]=" + buildTime("yy-MM-dd HH:mm"))
    builder.append("\r\n")
    builder.append("[版本编号]=" + vCode)
    builder.append("\r\n")
    builder.append("[版本名称]=" + vName)
    builder.append("\r\n")
    builder.append("[提交记录]=" + getGitVersion())
    fw.write(builder.toString())
    fw.flush();
    fw.close();
}

build {
    doLast {
        buildLog(mOutputs,mVersionName,mVersionProps['VERSION_CODE'])
        copy {
            from "$buildDir/outputs/mapping"
            into mOutputs
        }
    }
}

task mak{
    buildLog(mOutputs,mVersionName,mVersionProps['VERSION_CODE'])
}

打包只需终端输入

//--info或者--debug输出详细信息,方便出错时候定位错误
gradle clean
gradle build --info

输出

小结一下,方便以后打包处理更为方便,当然Gradle的强大之处远不止如此

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容