Gradle 多渠道打包实践
来源:互联网 发布:mac怎么安装第三方软件 编辑:程序博客网 时间:2024/06/05 00:19
公司现在用的是 ANT 来打包 apk。昨晚学习了一下用命令行使用 Gradle 打包,先总结,以后用得上。
这篇文章,只讲“是什么”、“怎么做”,至于“为什么”这里先不弄清楚,先把打包这个任务完成以后再来说这个。
配置友盟环境
在 AndroidManifest.xml 的 <application> 标签中添加相关信息:APP_KEY 和渠道号。在这里,渠道号只是一个占位符,在打包的阶段可以动态地替换占位符里的信息。
<application ... > <meta-data android:name="UMENG_APPKEY" android:value="@string/UMENG_APPKEY"/> <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_ID}"/> ...</application>
配置签名信息
在 app
的 module 中的 build.gradle
添加下列信息:别名、别名密码、签名文件地址和签名密码
signingConfigs { release { keyAlias 'xxx' keyPassword 'xxx' storeFile file('C:/Users/Administrator/Desktop/xxx.jks') storePassword 'xxx' }}
设置 buildTypes 的签名配置
因为要打 release 包,所以需要设置 buildTypes 为 release 的签名配置,如下
buildTypes { release { zipAlignEnabled true minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release // 加上这句话即可 }}
配置渠道信息
渠道号是自己定的,比如:wandoujia(豌豆荚)、baidu(百度)、google(Play Store)等等,想取什么名字就取什么名字。不过不要使用数字开头的命名方式。也不要使用unknow
这样的名字,因为友盟不允许取这个名字。
还记不记得前面讲的渠道号占位符:${UMENG_CHANNEL_ID}
,这里要做的就是动态的替换占位符的内容。配置信息如下:
productFlavors { baidu { manifestPlaceholders = [UMENG_CHANNEL_ID: "baidu"] } google { manifestPlaceholders = [UMENG_CHANNEL_ID: "google"] } wandoujia { manifestPlaceholders = [UMENG_CHANNEL_ID: "wandoujia"] } xiaomi { manifestPlaceholders = [UMENG_CHANNEL_ID: "xiaomi"] } owen { manifestPlaceholders = [UMENG_CHANNEL_ID: "owen"] }}
执行打包命令
到这里,相关的配置已经全部完成了,可以执行打包命令了,在控制台输入下面这两条命令
gradlew cleangradlew assembleRelease
打包好的 apk 文件就放在 app module 的 build\outputs\apk
文件夹下
完整的 build.gradle 配置
apply plugin: 'com.android.application'android { signingConfigs { // 签名配置 release { keyAlias 'xxx' keyPassword 'xxx' storeFile file('C:/Users/Administrator/Desktop/xxx.jks') storePassword 'xxx' } } compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.owen.packapk" minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { // buildTypes 配置 zipAlignEnabled true minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } productFlavors { // 渠道配置 baidu { manifestPlaceholders = [UMENG_CHANNEL_ID: "baidu"] } google { manifestPlaceholders = [UMENG_CHANNEL_ID: "google"] } wandoujia { manifestPlaceholders = [UMENG_CHANNEL_ID: "wandoujia"] } xiaomi { manifestPlaceholders = [UMENG_CHANNEL_ID: "xiaomi"] } owen { manifestPlaceholders = [UMENG_CHANNEL_ID: "owen"] } }}dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0'}
以上就打打包的全部内容了,做到这里就可以完成打包任务了。不过还有一些地方可以优化。
隐藏签名信息
签名信息这种东西属于私密的信息,应该保护起来,最好不要明文写到 build.gradle 里,更不要上传到代码仓库中去。应该放在单独的文件中,在 build.gradle 里去引用这个文件读取签名信息。
清空 signingConfigs
signingConfigs { release { }}
在 app module 中新建一个文件 signing.properties
,填入签名信息
STORE_FILE=C:/Users/Administrator/Desktop/XXX.jksSTORE_PASSWORD=XXXKEY_ALIAS=XXXKEY_PASSWORD=XXX
在 build.gradle 里添加下列代码去读取这个文件中的签名信息。
File propFile = file('signing.properties');if (propFile.exists()) { def Properties props = new Properties() props.load(new FileInputStream(propFile)) if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') && props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) { android.signingConfigs.release.storeFile = file(props['STORE_FILE']) android.signingConfigs.release.storePassword = props['STORE_PASSWORD'] android.signingConfigs.release.keyAlias = props['KEY_ALIAS'] android.signingConfigs.release.keyPassword = props['KEY_PASSWORD'] } else { android.buildTypes.release.signingConfig = null }} else { android.buildTypes.release.signingConfig = null}
signing.properties
这个文件不能上传到代码仓库里去,所以要在 .gitignore
文件中添加一句话
signing.properties
经过这几个步骤,就实现了保护签名信息的需求。
简化渠道号配置信息的写法
之前的渠道信息是这么写的
productFlavors { baidu { manifestPlaceholders = [UMENG_CHANNEL_ID: "baidu"] } google { manifestPlaceholders = [UMENG_CHANNEL_ID: "google"] } wandoujia { manifestPlaceholders = [UMENG_CHANNEL_ID: "wandoujia"] } xiaomi { manifestPlaceholders = [UMENG_CHANNEL_ID: "xiaomi"] } owen { manifestPlaceholders = [UMENG_CHANNEL_ID: "owen"] }}
可以发现这些配置信息的写法都差不多,有一定规律。所以,还可以简写成这样
productFlavors { baidu {} google {} wandoujia {} xiaomi {} owen {}}productFlavors.all { flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_ID: flavor.name]}
跟踪打包过程
建议在命令后面加上 --stacktrace
参数,这样万一命令执行失败,可以看到详细的出错信息
gradlew clean --stacktracegradlew assembleRelease --stacktrace
定制 APK 的文件名
默认情况下,打包好的 APK 的文件名是这样的
我想要的这样的文件名:app_版本名称_版本号_日期_渠道号.apk
,可以添加如下信息
def packageTime() { return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))}android { applicationVariants.all { variant -> variant.outputs.each { output -> // 重命名产出的apk文件 def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { File outputDirectory = new File(outputFile.parent); def fileName if (variant.buildType.name == "release") { fileName = "app_v${defaultConfig.versionName}_${defaultConfig.versionCode}_${packageTime()}_${variant.productFlavors[0].name}.apk" } else { fileName = "app_v${defaultConfig.versionName}_${defaultConfig.versionCode}_${packageTime()}_debug.apk" } output.outputFile = new File(outputDirectory, fileName) } } }}
打包结果如图:
删除冗余的 unaligned apk 文件
在 app/build/outputs/apk 文件夹中,可以看到一些文件名末尾带有 unaligned
文字的冗余文件,这些文件没有用,可以删掉,只需要在 build.gradle 中添加下列命令就好了
applicationVariants.all { variant -> variant.outputs.each { output -> // 重命名产出的apk文件 def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { File outputDirectory = new File(outputFile.parent); def fileName if (variant.buildType.name == "release") { fileName = "app_v${defaultConfig.versionName}_${defaultConfig.versionCode}_${packageTime()}_${variant.productFlavors[0].name}.apk" } else { fileName = "app_v${defaultConfig.versionName}_${defaultConfig.versionCode}_${packageTime()}_debug.apk" } output.outputFile = new File(outputDirectory, fileName) } // 删除unaligned apk if (output.zipAlign != null) { output.zipAlign.doLast { output.zipAlign.inputFile.delete() } } }}
打包之后,就没有这些冗余文件了
Github
完整项目地址在这里:https://github.com/owenmike/packApk
总结
多渠道打包的步骤:
- 配置 AndroidManifest.xml
- 配置签名信息
- 配置渠道号信息
- 定制与优化
原文链接:http://www.jianshu.com/p/7236ceca2630
这种打包其实很耗时,当你的渠道超过10个的时候估计很麻烦,其实有更快的方法:
http://www.jianshu.com/p/e0783783d26d
- Gradle 多渠道打包实践
- Gradle多渠道打包
- Gradle多渠道打包
- eclipse+gradle多渠道打包
- 【Andorid】Gradle多渠道打包
- android Gradle多渠道打包
- eclipse多渠道打包(gradle)
- Gradle多渠道打包 (1)
- Gradle多渠道打包
- gradle多渠道打包
- Gradle多渠道打包
- Gradle 多渠道打包
- 使用gradle多渠道打包
- Gradle多渠道打包
- Gradle Android 多渠道打包
- 多渠道打包(Gradle配置)
- Gradle多渠道打包
- Gradle配置多渠道打包
- hdu 2227(树状数组优化dp)
- HDU 3474 单调队列
- 【Apache Shiro】学习笔记——Authentication基础
- Android Studio – 使用百度地图SDK教程
- 漫谈deepcopy(深拷贝)和shallowcopy(浅拷贝)
- Gradle 多渠道打包实践
- 第16周阅读程序4(2)
- 短信验证
- 物理层及数据通信基础
- elasticsearch 复杂查询 模板查询
- spring MVC配置详解
- scrollview和viewpager联动
- Activity的简介
- 论文:Deep Face Recognition 概括
程序猴: @cyning 美团方案确实不错,不过这个方案还需要注意一点,需要重新执行一下zipAligned才比较合适