Gradle 自定义Task
自定义task 实现自动化系统签名,push安装,重启设备等操作
Task 实现 apk系统签名
原先打系统apk包需要将build/outputs/apk下面的apk安装包拿出来,执行java命令java -jar signapk.jar platform.x509.pem platform.pk8 xxx.apk xxxSysSign.apk
生成 xxxSysSign.apk
的系统包。
现想法就是自定义一个task,能在assembleDebug
执行系统签名操作。因为系统签名实质上就是执行一行java命令的操作。
先把系统签名需要的文件 signapk.jar
platform.x509.pem
platform.pk8
放到 app模块根目录下,也就是与app模块的build.gradle
同级,然后在该build.gradle
文件里新增一个task(与android {}同级,不要写在android{}里面),具体如下:
task autoSignDebug {
def outputFileName = "WeierV1.0.0.0.apk"
dependsOn 'assembleDebug'
doLast { // 系统应用签名
File file = new File("./app/build/outSignApk");
if (!file.exists())
file.mkdirs();
def result = ("java -jar signapk.jar platform.x509.pem platform.pk8 ./build/outputs/apk/Weier.apk ./build/outSignApk/" + outputFileName).execute([], new File('./app/')).text.trim()
println("apk系统签名完成 = " + result)
}
}
简单解释下:
dependsOn 'assembleDebug'
意思就是依赖于assembleDebug
task,这个task就是gradle自带的用来 生成 debug版安装包的 task。依赖于assembleDebug
,就是指执行该task前将先执行assembleDebug
。同样也可以将代码里的assembleDebug
替换成assembleRelese
doLast{}
doFirst和doLast中的代码,不执行这个任务时,是不会执行的,但是直接写在闭包中的,就也是在这两个函数外的代码,是在配置阶段就会执行的。运行任务时,doFirst中的代码最先执行,doLast中的代码最后执行。再解释下
"xxxx".execute([], new File('./app/')).text.trim()
这个语句。查阅execute()
方法源码,最终实现就是Runtime.java
里的Process exec(String prog, String[] envp, File directory)
方法,.text.trim()
方法会返回执行命名行的结果。
所以这个autoSignDebug
task,就是在assembleDebug
之后执行 新建 outSignApk 文件夹,并生成 系统签名apk,最终打印结果 。
实现后续功能,push安装 、重启设备
push安装与重启,其实就是adb命令集,所以参照之前的思路就很简单了,只要再加一个doLast{}
语句执行几个adb命令即可:
doLast { //安装新应用
def outputFilePath = "./build/outSignApk/" + outputFileName
// 设备系统 暂时只支持push安装系统app
("adb root").execute([], new File('./')).text.trim()
def result = ("adb push " + outputFilePath + " /wellcom/app/Weier/Weier.apk").execute([], new File('./app/')).text.trim()
println("apk安装 完成=" + result)
//伪重启
("adb shell stop").execute([], new File('./')).text.trim()
("adb shell start").execute([], new File('./')).text.trim()
}
这里的push安装也可以换成install安装"adb install -r " + outputFilePath
,还可以在安装前先执行卸载操作"adb uninstall " + android.defaultConfig.applicationId
所以最终task代码:
task autoSignDebug {
def outputFileName = "WeierV1.0.0.0.apk"
dependsOn 'assembleDebug'
doLast { // 系统应用签名
File file = new File("./app/build/outSignApk");
if (!file.exists())
file.mkdirs();
def result = ("java -jar signapk.jar platform.x509.pem platform.pk8 ./build/outputs/apk/Weier.apk ./build/outSignApk/" + outputFileName).execute([], new File('./app/')).text.trim()
println("apk系统签名完成 = " + result)
}
doLast { //卸载老应用
// commandLine 'adb', 'uninstall', android.defaultConfig.applicationId
// ("adb uninstall " + android.defaultConfig.applicationId).execute([], new File('./'))
}
doLast { //安装新应用
def outputFilePath = "./build/outSignApk/" + outputFileName
// ("adb install -r " + outputFilePath).execute([], new File('./'))
// 设备系统 暂时只支持push安装app
("adb root").execute([], new File('./')).text.trim()
def result = ("adb push " + outputFilePath + " /wellcom/app/Weier/Weier.apk").execute([], new File('./app/')).text.trim()
println("apk安装 完成=" + result)
//重启
("adb shell stop").execute([], new File('./')).text.trim()
("adb shell start").execute([], new File('./')).text.trim()
}
}
其实还可以做很多事情,比如统计每个命令的耗时,或者apk命名加上时间和版本号等简单功能。