gradle+360加固宝实现自动化打包、加固、签名输出
由于我司应用已经上架到各大应用市场,每次发布版本都要:先打包,然后打开360加固宝,上传安装包,等待加固,加固完再手动下载然后上传应用市场,整个过程特别麻烦。为了偷懒就想着有没有更方便的方法,打包完成自动加固签名,于是网上搜索了一堆gradle自动化打包加固的插件,想象很美好引入别人封装的加固插件,发现打包完成并不能成功调用360加固。折腾了2天,发现这些插件其多是针对windows环境的,而我使用的是mac环境开发。所以便有了这篇文章,借此记录下自己遇到的问题,也希望能帮到使用mac开发的安卓童鞋。
好了下面直接上代码:(其实也不算代码,主要就是一个.gradle脚本文件)
首先:
出于安全考虑,keystore/jks 文件路径、密码等建议放在local.properties文件中,如下:
#你们自己的签名文件路径
STORE_FILE=/Users/laowang/keysore/demo.jks
#签名文件秘码
STORE_PASSWORD=demo123456
#签名文件别名
KEY_ALIAS=demo
KEY_PASSWORD=demo123456
#你自己的360用户名
JiaGuUserName=testjiagu
#你自己的360密码
JiaGuPassword=123456789
新建加固gradle脚本:
在app目录下,(注意:是app目录下,不是项目根目录下)新建一个名为pack.gradle的文件,至于前缀名字叫啥你随意【doge】,内容如下:
/**
* description:360自动加固
*/
// 把敏感信息存放到自定义的properties文件中
def propertiesFile = rootProject.file("local.properties")
def properties = new Properties()
properties.load(new FileInputStream(propertiesFile))
ext {
// 签名配置
signing = [keyAlias : properties['KEY_ALIAS'],
keyPassword : properties['STORE_PASSWORD'],
storeFile : properties['STORE_FILE'],
storePassword: properties['STORE_PASSWORD']
]
// app相关的配置
app = [
//默认release apk的文件路径,因为加固是基于release包的
releasePath: "${project.buildDir}/outputs/apk/release",
//对release apk 加固后产生的加固apk地址
packersPath: "${project.buildDir}/outputs/packers",
]
// 360加固配置
packers = [account : properties['JiaGuUserName'], //账号
password : properties['JiaGuPassword'], //密码
zipPath : "${project.rootDir}/jiagu/360jiagu.zip", //加固压缩包路径
unzipPath : "${project.rootDir}/jiagu/360jiagu/", //加固解压路径
jiaguPath : "${project.rootDir}/jiagu/360jiagu/360jiagubao/jiagu/",
jarPath : "${project.rootDir}/jiagu/360jiagu/360jiagubao/jiagu/jiagu.jar", //执行命令的jar包路径
channelConfigPath: "${project.rootDir}/jiagu/Channel.txt", //加固多渠道
jiagubao_mac : "https://down.360safe.com/360Jiagu/360jiagubao_mac.zip", //加固mac下载地址
jiagubao_windows : "https://down.360safe.com/360Jiagu/360jiagubao_windows_64.zip", //加固widnows下载地址
windowsCmdStart : 'java', //windows环境下java命令开头
macCmdStart : 'java/bin/java',//mac环境下java命令开头
]
}
/**
* 360加固,适用于新后台打包
*/
task packersNewRelease {
group 'packers'
dependsOn 'assembleRelease'
doLast {
//删除加固后的渠道包
deleteFile()
// 下载360加固文件
download360jiagu()
// 寻找打包文件release apk
def releaseFile = findReleaseApk()
if (releaseFile != null) {
//执行加固签名
packers360(releaseFile)
} else {
println 'packers===can't find release apk and can't excute 360 jiagu'
}
}
}
/**
* 加固后,打新版本的渠道包时,同时生成老版本的渠道包
*/
task packersRelease {
group 'packers'
dependsOn packersNewRelease
doLast {
println "packers===packersRelease finished"
}
}
/**
* 对于release apk 进行360加固
*/
def packers360(File releaseApk) {
println 'packers===beginning 360 jiagu'
def packersFile = file(app["packersPath"])
if (!packersFile.exists()) {
packersFile.mkdir()
}
exec {
workingDir(packers["jiaguPath"])
// 登录360加固保
executable = isWindows() ? packers["windowsCmdStart"] : packers["macCmdStart"]
args = ['-jar', packers["jarPath"], '-login', packers["account"], packers["password"]]
println 'packers===import 360 login'
}
exec {
workingDir(packers["jiaguPath"])
// 导入签名信息
executable = isWindows() ? packers["windowsCmdStart"] : packers["macCmdStart"]
args = ['-jar', packers["jarPath"], '-importsign', signing["storeFile"],
signing["storePassword"], signing["keyAlias"], signing["keyPassword"]]
println 'packers===import 360 sign'
}
exec {
workingDir(packers["jiaguPath"])
// 查看360加固签名信息
executable = isWindows() ? packers["windowsCmdStart"] : packers["macCmdStart"]
args = ['-jar', packers["jarPath"], '-showsign']
println 'packers===show 360 sign'
}
exec {
workingDir(packers["jiaguPath"])
// 初始化加固服务配置,后面可不带参数
executable = isWindows() ? packers["windowsCmdStart"] : packers["macCmdStart"]
args = ['-jar', packers["jarPath"], '-config']
println 'packers===init 360 services'
}
exec {
workingDir(packers["jiaguPath"])
// 执行加固
executable = isWindows() ? packers["windowsCmdStart"] : packers["macCmdStart"]
args = ['-jar', packers["jarPath"], '-jiagu', releaseApk.absolutePath, app["packersPath"], '-autosign']
println 'packers===excute 360 jiagu'
}
println 'packers===360 jiagu finished'
println "packers===360 jiagu path ${app["packersPath"]}"
}
/**
* 自动下载360加固保,也可以自己下载然后放到根目录
*/
def download360jiagu() {
// 下载360压缩包
File zipFile = file(packers["zipPath"])
if (!zipFile.exists()) {
if (!zipFile.parentFile.exists()) {
zipFile.parentFile.mkdirs()
println("packers===create parentFile jiagu ${zipFile.parentFile.absolutePath}")
}
// 加固保的下载地址
def downloadUrl = isWindows() ? packers["jiagubao_windows"] : packers["jiagubao_mac"]
// mac自带curl命令 windows需要下载curl安装
def cmd = "curl -o ${packers["zipPath"]} ${downloadUrl}"
println cmd
cmd.execute().waitForProcessOutput(System.out, System.err)
}
File unzipFile = file(packers["unzipPath"])
if (!unzipFile.exists()) {
//解压 Zip 文件
ant.unzip(src: packers["zipPath"], dest: packers["unzipPath"], encoding: "GBK")
//println "unZipFile child == ${unzipFile.listFiles()[0].name}"
//重命名加固文件夹
File jiaguFile = unzipFile.listFiles()[0]
String filePath="${jiaguFile.parentFile.path}/360jiagubao"
File newFile= file(filePath)
jiaguFile.renameTo(newFile)
println 'packers===unzip 360jiagu'
//将解压后的文件开启读写权限,防止执行 Jar 文件没有权限执行,windows需要自己手动改
if (!isWindows()) {
def cmd = "chmod -R 777 ${packers["unzipPath"]}"
println cmd
cmd.execute().waitForProcessOutput(System.out, System.err)
}
}
}
/**
* 是否是windows系统
* @return
*/
static Boolean isWindows() {
return System.properties['os.name'].contains('Windows')
}
/**
* 寻找本地的release apk
* @return true
*/
def deleteFile() {
delete app["packersPath"]
println 'packers===delete all file'
}
/**
* 首先打一个release包,然后找到当前的文件进行加固
* @return releaseApk
*/
def findReleaseApk() {
def apkDir = file(app["releasePath"])
File releaseApk = apkDir.listFiles().find { it.isFile() && it.name.endsWith(".apk") }
println "packers===find release apk ${releaseApk.name}"
return releaseApk
}
/**
* 加固输出并且重新命名
* @return packersApk
*/
def outputpackersApk() {
File oldApkDir = file(app["packersPath"])
File oldApk = oldApkDir.listFiles().find { it.isFile() && it.name.contains("jiagu") }
println "packers===output pacckers sourceApk ${oldApk.name}"
copy {
from app["packersPath"] + File.separator + oldApk.name
into app["packersPath"]
rename(oldApk.name, "release.apk")
println 'packers===output pacckers renameApk release.apk'
}
File newApk = oldApkDir.listFiles().find { it.isFile() && it.name.equals("release.apk") }
println "packers===output packers renameApk${newApk.absolutePath}"
return newApk.absolutePath
}
使用:
在app目录下的build.gradle 中引用我们上面新建的pack.gradle文件:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
//放在plugin闭包下面
//360加固签名配置脚本
apply from :"pack.gradle"
在项目terminal窗口输入:./gradlew packersNewRelease
等待打包加固完即可。如果不想输入命令也可以这样:
看到下面的输出结果,说明你成功了(oh yeah):