使用Gradle构建Android项目的一些自定义配置

最近开始养成了写博客的习惯。。。。希望后续能写出更高质量的文章。。

由于工作项目的需要,我往往需要一份代码>多份资源>多个app。
然而每个app都有自己的包名,id,微信id…等等一系列的参数,这些参数 有的需要写在中 有的需要写在代码内,写在String.xml中又增加了不安全的因素,导致非常难封装到一个文件内,加上当年用Eclipse工具开发,修改包名都要两分钟,编译也非常慢,有时甚至会卡死掉,真是蛋疼死了。
自从Android studio正式被推出,附带了Gradle这强大的东西,感觉从原始社会一下穿越到了现代。
说着说着 扯远了,简单写一下我在使用Gradle构建Android项目时的一些记录或者也可以称其为笔记的一些东西:

gradle可以定义res文件、方法函数、配置参数,并且可在 .class文件、Manifest文件以及gradle自身 中被直接调用。

自定义配置

支持定义BuildConfig值和res的值

  • 配置:可以在节点 defaultConfig、buildType、productFlavors 中配置:
    defaultConfig {
        applicationId "wenld.moon.color"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName 1.0
        resValue "string", "main_title", "name"       //    代码内调用方式:  R.string maintitle
        buildConfigField "boolean", "IS_LOG", "true"    //  代码内调用方式:  BuildConfig.IS_LOG
    }
    buildTypes {
        release {
            resValue "string", "main_title", "name"      
            buildConfigField "boolean", "IS_LOG", "true"   
            signingConfig signingConfigs.release
        }
    }
    productFlavors {
        miui {
            resValue "string", "main_title", "name"       
            buildConfigField "boolean", "IS_LOG", "true"   
        }
        wandoujia {
            resValue "string", "main_title", "name"       
            buildConfigField "boolean", "IS_LOG", "true"   
        }
    }
  • 调用:在代码中通过 BuildConfig.IS_LOGR.string.main_title 调用即可。

Manifest文件内容占位符

对Manifest进行自定义配置,使用方法:

  • 在Manifest文件中定义一个占位符,比如以信鸽推送的Id 例子为例,${XG_V2_ACCESS_ID},这种格式.
  • 在gradle配置文件中加替换,可以在节点 defaultConfig、buildType、productFlavors 中配置,比如:
defaultConfig {
        applicationId "wenld.moon.color"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName 1.0
        manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
    }
    buildTypes {
        release {
            manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
            signingConfig signingConfigs.release
        }
    }
    productFlavors {
        miui {
            manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
        }
        wandoujia {
            manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
        }
    }

同时,还可以直接在Manifest文件中用于包名的替换,直接使用${XG_V2_ACCESS_ID}即可。

定义函数

  • 配置:如下
def packageTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
  • 调用: ${packageTime()} 返回值: “2016-03-03”

自定义配置虽然简单,但是功能很强大,可以扩展很多不同的应用场景,比如可以定义测试和正式版本的信鸽推送的ID以及多渠道打包等等,就不一一列举了,自己去尝试扩展成自己的场景吧。

签名部分

gradle本身直接支持签名,只需要在releas部分添加以下代码即可

signingConfigs {
        debug {

        }
        release {
            storeFile file("../yourapp.keystore")
            storePassword "your password"
            keyAlias "your alias"
            keyPassword "your password"
        }
    }

    buildTypes {
        debug {
            minifyEnabled false
            zipAlignEnabled false
            shrinkResources false
            signingConfig signingConfigs.debug
        }

        release {
            minifyEnabled true//混淆编译
            zipAlignEnabled true
            //移除无用的资源文件
            shrinkResources true
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

一般填上上面的代码即可执行签名,但是一般这种方式不太安全,一般建议不要在build.gradle文件中写上签名文件的密码,这是由于build.gradle文件一般都会集成到代码的版本控制中,这样所有人都会有签名文件的密码,会有后续的麻烦。
可参考:Gradle构建项目时,将敏感信息保存在build.gradle之外

最终

上面说明了一下 如何在gradle中自定义配置参数、调用方法和如何gradle引入外部文件Gradle构建项目时,将敏感信息保存在build.gradle之外。
献上完整配置:

  • version.properties:
VERSION_CODE=1
VERSION_NAME=1.0
APPLICTION_ID=wenld.moon.color
APP_NAME="xiaojiaDoctor"
XG_V2_ACCESS_ID=sddffa8293d


storefile=Keystore_MH.keystore
keyAlias=MH
KEYSTORE_PASSWORD=password123
KEY_PASSWORD=password789
  • builde.gradle:
apply plugin: 'com.android.application'

def packageTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

def versionPropsFile = file("version.properties")//引入文件
Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))//读取文件
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId versionProps['APPLICTION_ID'].toString()//取出参数
        minSdkVersion 14
        targetSdkVersion 23
        versionCode versionProps['VERSION_CODE'].toInteger()
        versionName versionProps['VERSION_NAME'].toString()
        resValue "string", "app_name", (new String(versionProps['APP_NAME'].toString().getBytes("ISO-8859-1"), "UTF-8"))
        manifestPlaceholders = [
                XG_V2_ACCESS_ID: versionProps['XG_V2_ACCESS_ID'].toString()] //
    }
    signingConfigs { //签名配置
        release {
            storeFile file(versionProps['storefile'].toString())
            storePassword versionProps['KEYSTORE_PASSWORD'].toString()
            keyAlias versionProps['keyAlias'].toString()
            keyPassword versionProps['KEY_PASSWORD'].toString()
        }
        debug {

        }
    }
    buildTypes {
        release {
            minifyEnabled false//混淆编译
            shrinkResources true //移除无用的资源文件
            zipAlignEnabled true      //是否zip对齐
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            resValue "string", "main_title", "name" // 代码内调用方式: R.string maintitle

        }
        debug {
            minifyEnabled false
            shrinkResources true
            zipAlignEnabled true    

            resValue "string", "main_title", "debug_Name"  //调试版本的标题
        }
    }
    //修改生成的最终文件名
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                File outputDirectory = new File(outputFile.parent);
                def fileName
                if (variant.buildType.name == "release") {
                    // 输出apk名称为app_v1.0_2016-03-03.apk
                    fileName = "${defaultConfig.applicationId}_v${defaultConfig.versionName}_${packageTime()}}.apk"
                } else {
                    fileName = "${defaultConfig.applicationId}_v${defaultConfig.versionName}_${packageTime()}_beta.apk"
                }
                output.outputFile = new File(outputDirectory, fileName)
            }
        }
    }
    productFlavors {
        miui {
        }
        wandoujia {

        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar']
}

这样我们就可以 配置多个 .properties。在budle.gradle中调用以下代码即可生成不同的apk。

def versionPropsFile = file("version.properties")

推荐:

  • 解决方法数超65536限制
  • 多渠道打包插件:http://www.open-open.com/lib/view/open1438668666911.html
  • gradle 增量编译:http://www.lxway.com/572786.html

参考:

  • http://frank-zhu.github.io/android/2015/06/15/android-release_app_build_gradle/;
  • http://www.open-open.com/lib/view/open1439216256770.html
  • http://blog.isming.me/2014/11/21/use-gradle-new/

你可能感兴趣的:(release,多渠道打包,manifestPl,resValue,gradle构建)