当前位置:   article > 正文

Android Studio使用Gradle实现自动打包,签名,自定义apk文件名,多渠道打包,集成系统签名证书【附效果图附源码】_android build.gradle添加打包证书信息

android build.gradle添加打包证书信息

转载请注明出处,原文地址:http://blog.csdn.net/lucherr/article/details/72436018


        接触Android Stuidio有一阵子了,之前用的时候有很多小问题,不过现在的版本感觉已经很好用了,所以准备彻底从Eclipse转战Android Stuidio,这段时间把以前经常使用的公用库都从Eclipse移植过来了,今天研究了一下在Android Studio下进行打包签名之类的操作,其实主要是研究Gradle了,以前没有用过Gradle,但是早就耳闻Gradle是非常强大的构建系统,经过一天的奋战,最终实现了通过Gradle脚本来实现打包,签名,自定义文件名,多渠道打包,集成系统签名证书的功能,现在整理成一个demo来记录下实现的要点,以供大家参考和以后查阅。ps:这篇博客是这几天的第三篇博客了,算是弥补下这两年多的空缺:)


开始之前先看看作者的主要开发环境:
System:              Ubuntu14.04   
Android Studio:     V2.3.1
Gradle:                  V3.3


(一)先看下效果图

在Terminal里进入.config文件夹,执行./build.sh,或者直接从文件管理器里双击build.sh文件,打包任务开始。



然后就交给Gradle了,下图是执行完成时的截图,桌面右上角弹出通知,build/outputs/apk下生成签名并且按照指定规则命名后的apk



(二)build.gradle配置说明

引用自:http://blog.csdn.net/jjwwmlp456/article/details/45057067 在此表示感谢

在android{}模块中可以包含以下直接配置项:
defaultConfig{} 默认配置,是ProductFlavor类型。它共享给其他ProductFlavor使用
sourceSets{ } 源文件目录设置,是AndroidSourceSet类型。
buildTypes{ } BuildType类型
signingConfigs{ } 签名配置,SigningConfig类型
productFlavors{ } 产品风格配置,ProductFlavor类型
testOptions{ } 测试配置,TestOptions类型
aaptOptions{ } aapt配置,AaptOptions类型
lintOptions{ } lint配置,LintOptions类型
dexOptions{ } dex配置,DexOptions类型
compileOptions{ } 编译配置,CompileOptions类型
packagingOptions{ } PackagingOptions类型
jacoco{ } JacocoExtension类型。 用于设定 jacoco版本
splits{ } Splits类型。


(三)脚本构建

下面所说的某些脚本AS会自动生成默认配置,某些可以通过File>Project Structure进行添加,然后可以在此基础上进行修改。



1.添加签名脚本,指定签名文件相关配置

签名功能可以使用Build>Generate Signed APK来实现,不过作者追求的是全自动化,完全交给Gradle,提高效率哈哈,多说一句,这里的证书也可以是eclipse下生成的.keystore文件

  1. //签名配置
  2. signingConfigs {
  3. config {
  4. keyAlias 'lucher' //key别名
  5. keyPassword 'lucher' //key密码,最好不要配置在脚本里
  6. storeFile file('/home/lucher/main/sign/lucher.jks') //证书路径,证书最好不要放入项目源码
  7. storePassword 'lucher' //证书密码,最好不要配置在脚本里
  8. }
  9. }

2.添加编译类型脚本(AS会自动生成默认的release配置)
  1. //编译类型
  2. buildTypes {
  3. release {
  4. minifyEnabled false
  5. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  6. signingConfig signingConfigs.config //加入签名配置
  7. }
  8. debug {//debug类型
  9. debuggable true //启用debug的buildType配置
  10. }
  11. custom {//自定义类型
  12. minifyEnabled false
  13. renderscriptDebuggable true
  14. }
  15. }

3.添加产品风格配置脚本,可用于多渠道打包

友盟统计是使用较多的渠道统计工具,按照友盟官方文档说明,渠道信息需要在AndroidManifest.xml中配置如下值:
<meta-data    android:name="UMENG_CHANNEL"    android:value="${UMENG_CHANNEL_VALUE}" />

这个功能可以通过该脚本来配置,为不同渠道定义不同Value(还可以为不同产品配置不同的应用名称,通过manifestPlaceholders = [  APP_NAME  : "app-name"]来配置,然后需要把AndroidManifest.xml里application标签下的label改为: android:label="${APP_NAME}",该脚本在示例源码里没有加入)

  1. //产品风格配置,可用于多渠道打包
  2. productFlavors {
  3. //百度推广渠道
  4. baidu {
  5. applicationId "com.lucher.myapplication"
  6. versionCode 1
  7. versionName "1.0"
  8. manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
  9. manifestPlaceholders = [ APP_NAME : "app-百度"] //自定义App名称,需要把AndroidManifest.xml里的label改为: android:label="${APP_NAME}"
  10. }
  11. //360推广渠道
  12. qh360 {
  13. applicationId "com.lucher.myapplication"
  14. versionCode 1
  15. versionName "1.0"
  16. manifestPlaceholders = [UMENG_CHANNEL_VALUE: "qh360"]
  17. manifestPlaceholders = [ APP_NAME : "app-360"] //自定义App名称,需要把AndroidManifest.xml里的label改为: android:label="${APP_NAME}"
  18. }
  19. //豌豆荚推广渠道
  20. wandoujia {
  21. applicationId "com.lucher.myapplication"
  22. versionCode 1
  23. versionName "1.0"
  24. manifestPlaceholders = [ APP_NAME : "app-豌豆荚"] //自定义App名称,需要把AndroidManifest.xml里的label改为: android:label="${APP_NAME}"
  25. }
  26. }

4.添加自定义apk名称脚本

有时候需要让apk以指定的规则来命名,可以通过该脚本来实现,本例中命名规则为:

module_flavor-version-time-buildtype.apk

在build.gradle里定义获取当前时间方法(方法定义需要放在android之外)

  1. //获取当前时间
  2. def getCurrentTime() {
  3. return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
  4. }

在android的android.applicationVariants.all方法里修改apk文件名

  1. //apk文件重命名
  2. android.applicationVariants.all { variant ->
  3. variant.outputs.each { output ->
  4. def outputFile = output.outputFile
  5. if (outputFile != null && outputFile.name.endsWith('.apk')) {
  6. def buildType = variant.buildType.name
  7. //这里修改apk文件名,格式为 module_flavor-version-time-buildtype.apk
  8. def fileName = "app_${variant.productFlavors[0].name}-V${defaultConfig.versionName}-${getCurrentTime()}-${buildType}.apk"
  9. output.outputFile = new File(outputFile.parent, fileName)
  10. }
  11. }
  12. }


(四)编译命令

注:在使用编译命令之前请确保gradle已经加入环境变量,如果没加入可以通过./gradlew替代gradle(只能在项目根目录下使用

1编译所有productFlavor及对应所有buildType的apk,相当于按照所有productFlavor和buildType的笛卡尔乘积生成对应的apk,本例中分别有三种productFlavor和三种buildType,生成了9个apk文件
$gradle assemble   //仅仅执行项目打包所必须的任务集
$gradle build           //执行项目打包所必须的任务集,以及执行自动化测试,所以会较慢
如果当前Project包含多个Module,在Project根目录执行gradle assemble会编译所有的Module

2编译指定productFlavor及buildType的apk
$gradle assemble[productFlavor][buildType]
如果缺失某参数,则会把该参数的所有配置都进行编译,即如果运行gradle assembleflavor,则会编译出flavor所有buildType的apk
例如:
$gradle assemble
$gradle assembleflavorRelease 
$gradle assembleflavorDebug

注:gradle支持命令缩写,上面两个命令也可以写成如下格式
$gradle a
$gradle ass
$gradle aR
$gradle assflavorR
$gradle aD
$gradle assflavorD


(五)集成系统签名证书

如果项目需要使用系统权限,则需要在AndroidManifest.xml文件里加入如下属性:

android:sharedUserId="android.uid.system"

加入该属性后apk需要用系统签名才能正常使用。
作者常用的是如下两种方法:
1.android源码环境下签名

需要源码环境,太麻烦
2.对apk进行重新签名

通过下面的命令进行签名

java -jar signapk.jar platform.x509.pem platform.pk8 demo.apk demo_s.apk

这两个方法除了麻烦,还有一个问题:没法直接在开发工具里调试,这是硬伤啊,以前基本都是先打包然后进行重新签名

今天了解到还有另外一个方法可以解决上面的问题,就是把系统签名相关信息导入到已经存在的签名文件里(可以是.jks或者.keystore)

这需要使用一个开源库keytool-importkeypair:https://github.com/getfatday/keytool-importkeypair

使用方法,以lucher.jks为例(需要在linux环境下执行,本例中用到的系统证书是从某系统源码里导出来的,在源码中的路径为:android/build/target/product/security/):

下载keytool-importkeypair,然后把platform.x509.pem platform.pk8 keytool-importkeypair lucher.jks放到同一个文件夹下,执行如下命令即可:
./keytool-importkeypair -k [jks文件名] -p [jks的密码] -pk8 platform.pk8 -cert platform.x509.pem -alias [jks的别名]
本例使用的命令为:
$./keytool-importkeypair -k lucher.jks -p lucher -pk8 platform.pk8 -cert platform.x509.pem -alias lucher
执行成功后会把系统签名信息导入到lucher.jks里,然后签名的方法同上面所说的方法一样,这里不在赘述

最后再强调一点:如果要直接在AS里通过Run运行,需要给Debug模式加上签名信息,或者可以通过左侧的Build Variant选择加入签名配置的模式运行


(六)进阶配置

一,把签名配置从源码移除

如果按照上面所述的方法进行签名配置的话,存在两个问题:

一是密码直接明文显示在gradle里,有严重安全隐患

二是如果多个人同时开发项目,证书的路径各不相同,各自需要修改证书路径.

解决办法:

对于问题一,可以让密码从终端控制行获取,但是这样在打包的时候还需要输入密码,怪麻烦的,跟我追求的完全自动化不符,所以不采用,这种方法可以查询相关资料

对于问题二,我的想法是把签名相关的配置从项目里分离出来,存放到本地配置文件,然后添加一个不需要提交到代码管理工具的配置文件,在该文件里指定分离出来的签名配置文件路径,最后在项目的gradle里加载该配置,这个想法同样可以解决问题一,把密码也写入到这个本地配置文件里

有了这个思路,然后就是研究怎么实现了,经过查阅资料,最后参考下面文章的方法实现了该功能:

https://www.timroes.de/2013/09/22/handling-signing-configs-with-gradle/

值得一提的是:该文章的方法是在gradle.properties里添加的本地签名配置文件路径,不过gradle.properties也加入了版本控制,所以作者使用另一个方法来实现,在项目根目录下新建.config/signgradle.txt文件

在该文件里指定了本地签名配置文件路径,本例为:

/home/lucher/main/sign/sign.gradle


下面说下具体实现步骤:
1.把需要签名的相关配置存放到本地的文件里,然后在项目里加载进来

在项目根目录新建 .config/signgradle.txt文件,内容为签名配置文件地址
/home/lucher/main/sign/sign.gradle

2.sign.gradle加入如下内容

  1. android {
  2.     signingConfigs {
  3.         release {
  4.             storeFile file('/home/lucher/main/sign/lucher.jks') //绝对路径
  5.             storePassword "lucher"
  6.             keyAlias "lucher"
  7.             keyPassword "lucher"
  8.         }
  9.     }
  10. //编译类型
  11. buildTypes {
  12. release {
  13. minifyEnabled false
  14. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  15. signingConfig signingConfigs.release
  16. }
  17. }
  18. }

3.在需要加入签名的gradle文件中加载该签名gradle文件
  1. //加载签名信息
  2. File configFile = file('../.config/signgradle.txt')
  3. if (configFile.exists()) {
  4. def signGradlePath = configFile.newReader().readLine().trim()
  5. println 'lucher, path:' + signGradlePath
  6. if (file(signGradlePath).exists()) {
  7. apply from: signGradlePath
  8. }
  9. }

4.移除原build.gradle文件中buildTypes/realease的定义

5.执行编译打包命令即可


二,编写编译脚本

Linux下编写shell脚本,Windows下编写bat脚本

本例只编写了shell脚本,即工程中.config/build.sh,内容如下:

  1. #快速编译打包apk脚本
  2. echo " **************************打包开始 ************************** "
  3. sleep 1
  4. #执行打包命令前,需要先定位到项目根目录
  5. cd ..
  6. #执行打包命令
  7. gradle a
  8. echo -e "**************************打包完成************************** "
  9. #桌面右上角弹出通知
  10. notify-send build.sh "打包完成!"
然后就可以直接通过./build.sh或者在文件管理器里双击build.sh文件来打包了,非常方便:)

内容有误还望指出


最后给出文中涉及到的资源下载地址,包括示例源码,签名配置信息,keytool-importkeypair(效果图中的app2是打酱油的,为了缩减文件,资源源码中已经去掉)

http://download.csdn.net/detail/lucherr/9845187


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/845367
推荐阅读
相关标签
  

闽ICP备14008679号