Gradle 自定義Task
自定義task 實(shí)現(xiàn)自動(dòng)化系統(tǒng)簽名,push安裝,重啟設(shè)備等操作
Task 實(shí)現(xiàn) apk系統(tǒng)簽名
原先打系統(tǒng)apk包需要將build/outputs/apk下面的apk安裝包拿出來,執(zhí)行java命令java -jar signapk.jar platform.x509.pem platform.pk8 xxx.apk xxxSysSign.apk生成 xxxSysSign.apk的系統(tǒng)包。
現(xiàn)想法就是自定義一個(gè)task,能在assembleDebug執(zhí)行系統(tǒng)簽名操作。因?yàn)橄到y(tǒng)簽名實(shí)質(zhì)上就是執(zhí)行一行java命令的操作。
先把系統(tǒng)簽名需要的文件 signapk.jar platform.x509.pem platform.pk8 放到 app模塊根目錄下,也就是與app模塊的build.gradle同級(jí),然后在該build.gradle文件里新增一個(gè)task(與android {}同級(jí),不要寫在android{}里面),具體如下:
task autoSignDebug {
def outputFileName = "WeierV1.0.0.0.apk"
dependsOn 'assembleDebug'
doLast { // 系統(tǒng)應(yīng)用簽名
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系統(tǒng)簽名完成 = " + result)
}
}
簡(jiǎn)單解釋下:
dependsOn 'assembleDebug'意思就是依賴于assembleDebugtask,這個(gè)task就是gradle自帶的用來 生成 debug版安裝包的 task。依賴于assembleDebug,就是指執(zhí)行該task前將先執(zhí)行assembleDebug。同樣也可以將代碼里的assembleDebug替換成assembleRelesedoLast{}doFirst和doLast中的代碼,不執(zhí)行這個(gè)任務(wù)時(shí),是不會(huì)執(zhí)行的,但是直接寫在閉包中的,就也是在這兩個(gè)函數(shù)外的代碼,是在配置階段就會(huì)執(zhí)行的。運(yùn)行任務(wù)時(shí),doFirst中的代碼最先執(zhí)行,doLast中的代碼最后執(zhí)行。再解釋下
"xxxx".execute([], new File('./app/')).text.trim()這個(gè)語句。查閱execute()方法源碼,最終實(shí)現(xiàn)就是Runtime.java里的Process exec(String prog, String[] envp, File directory)方法,.text.trim()方法會(huì)返回執(zhí)行命名行的結(jié)果。
所以這個(gè)autoSignDebug task,就是在assembleDebug之后執(zhí)行 新建 outSignApk 文件夾,并生成 系統(tǒng)簽名apk,最終打印結(jié)果 。
實(shí)現(xiàn)后續(xù)功能,push安裝 、重啟設(shè)備
push安裝與重啟,其實(shí)就是adb命令集,所以參照之前的思路就很簡(jiǎn)單了,只要再加一個(gè)doLast{}語句執(zhí)行幾個(gè)adb命令即可:
doLast { //安裝新應(yīng)用
def outputFilePath = "./build/outSignApk/" + outputFileName
// 設(shè)備系統(tǒng) 暫時(shí)只支持push安裝系統(tǒng)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,還可以在安裝前先執(zhí)行卸載操作"adb uninstall " + android.defaultConfig.applicationId
所以最終task代碼:
task autoSignDebug {
def outputFileName = "WeierV1.0.0.0.apk"
dependsOn 'assembleDebug'
doLast { // 系統(tǒng)應(yīng)用簽名
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系統(tǒng)簽名完成 = " + result)
}
doLast { //卸載老應(yīng)用
// commandLine 'adb', 'uninstall', android.defaultConfig.applicationId
// ("adb uninstall " + android.defaultConfig.applicationId).execute([], new File('./'))
}
doLast { //安裝新應(yīng)用
def outputFilePath = "./build/outSignApk/" + outputFileName
// ("adb install -r " + outputFilePath).execute([], new File('./'))
// 設(shè)備系統(tǒng) 暫時(shí)只支持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()
}
}
其實(shí)還可以做很多事情,比如統(tǒng)計(jì)每個(gè)命令的耗時(shí),或者apk命名加上時(shí)間和版本號(hào)等簡(jiǎn)單功能。