Android热修复框架设计Gradle自动化多渠道打包
Gradle是什么
Gradle是依赖管理构建工具。它继承了Ant的灵活和Maven的生命周期管理,它最后被google作为了Android御用管理工具。它最大的区别是不用XML作为配置文件格式,采用了DSL格式,使得脚本更加简洁。Ant是最早的构建工具,基于idea,好象是2000年有的,当时是最流行java构建工具,不过它的XML脚本编写格式让XML文件特别大。对工程构建过程中的过程控制特别好。Maven它是用来给Ant补坑的,Maven第一次支持了从网络上下载的功能,仍然采用xml作为配置文件格式,它的问题是不能很好的相同库文件的版本冲突。Maven专注的是依赖管理,构建神马的并不擅长。构建工具是什么单个源码文件,你可以很轻松地javac、gcc。然而项目结构复杂的时候,从源代码到实际产出的生成物之间需要经过一些列的转换操作,比如说编译、打包。而这一整个完整的过剩叫做构建。Maven的主要功能主要分为5点,分别是依赖管理系统、多模块构建、一致的项目结构、一致的构建模型和插件机制。gradle相关基础
gradle脚本插件的引用applyfrom:{project。rootDir}packers。gradle局部变量defdestA扩展属性使用ext扩展块,一次扩展多个属性ext{accountXXXXpasswordXXXXX}字符串相关单引号不支持插值defname‘张三’双引号支持插值defname我是{‘张三’}三个单引号支持换行defname张三李四可有可无的圆括号这两种写法等价println(‘A’)println‘A’闭包作为方法的最后一个参数repositories{printlnA}repositories(){printlnA}repositories({printlnA})task依赖taskB{TaskB依赖TaskA,故会先执行TaskAdependsOnA其次执行packersReleasedoLast{printlnB}}task排序taskB必须总是在taskA之后运行,无论taskA和taskB是否将要运行taskB。mustRunAfter(taskA)没有msut那么严格taskB。shouldRunAfter(taskA)文件定位使用一个相对路径FileconfigFilefile(‘srcconfig。xml’)使用一个绝对路径configFilefile(configFile。absolutePath)使用一个项目路径的文件对象configFilefile(newFile(‘srcconfig。xml’))文件遍历对文件集合进行迭代collection。each{Filefileprintlnfile。name}文件复制重命名copy{from源文件地址into目标目录地址rename(原文件名,新文件名字)}代码示例自动下载360加固保,也可以自己下载然后放到根目录defdownload360jiagu(){下载360压缩包FilezipFilefile(packers〔zipPath〕)if(!zipFile。exists()){if(!zipFile。parentFile。exists()){zipFile。parentFile。mkdirs()println(packerscreateparentFilejiagu{zipFile。parentFile。absolutePath})}加固保的下载地址defdownloadUrlisWindows()?packers〔jiagubaowindows〕:packers〔jiagubaomac〕mac自带curl命令windows需要下载curl安装defcmdcurlo{packers〔zipPath〕}{downloadUrl}printlncmdcmd。execute()。waitForProcessOutput(System。out,System。err)}FileunzipFilefile(packers〔unzipPath〕)if(!unzipFile。exists()){解压Zip文件ant。unzip(src:packers〔zipPath〕,dest:packers〔unzipPath〕,encoding:GBK)printlnpackersunzip360jiagu’将解压后的文件开启读写权限,防止执行Jar文件没有权限执行,windows若没有权限需要自己手动改if(!isWindows()){defcmdchmodR777{packers〔unzipPath〕}printlncmdcmd。execute()。waitForProcessOutput(System。out,System。err)}}}打一个release包
gradle其实为我们提供了一系列相关的任务,如下图
我们执行加固前是需要拿到一个release包的,所以我们可以利用assembleRelease在加固前先执行assembleRelease这个Task。taskpackersNewRelease{group‘packers’可以利用task的依赖关系先执行打包dependsOn‘assembleRelease’}自动执行加固
所谓自动执行加固,无非就是几行命令,360加固保提供了一套命令行进行加固
特别提醒,此处360配置可选项的增强服务有bug,已经跟官方沟通,他们需要在下个版本修复,当前存在bug的版本3。2。2。3(20200316),命令行目前无法只选择盗版监测对于releaseapk进行360加固defpackers360(FilereleaseApk){println‘packersbeginning360jiagu’defpackersFilefile(app〔packersPath〕)if(!packersFile。exists()){packersFile。mkdir()}exec{登录360加固保executable‘java’args〔’jar’,packers〔jarPath〕,‘login’,packers〔account〕,packers〔password〕〕printlnpackersimport360login’}exec{导入签名信息executable‘java’args〔’jar’,packers〔jarPath〕,‘importsign’,signing〔storeFile〕,signing〔storePassword〕,signing〔keyAlias〕,signing〔keyPassword〕〕println‘packersimport360sign’}exec{查看360加固签名信息executable‘java’args〔’jar’,packers〔jarPath〕,‘showsign’〕printlnpackersshow360sign’}exec{初始化加固服务配置,后面可不带参数executable‘java’args〔’jar’,packers〔jarPath〕,‘config’〕println‘packersinit360services’}exec{执行加固,然后自动签名,若不采取自动签名,需要自己通过buildtools命令自己签名executable‘java’args〔’jar’,packers〔jarPath〕,‘jiagu’,releaseApk。absolutePath,app〔packersPath〕,‘autosign’〕printlnpackersexcute360jiagu’}printlnpackers360jiagufinished’printlnpackers360jiagupath{app〔packersPath〕}}自动签名
关于自动签名,其实360在加固的时候提供了自动签名的配置选项,如果你不想将签名文件上传给360,在加固后可以自己选择手动签名,因为这涉及到安全性的问题,此版本我采取的是360自动签名,如果大家想自己手动签名,下面我给出一套方案,主要是利用zipalign和apksigner命令他们都是位于SDK文件中的buildtools目录中,我们执行自动化签名需要gradle配置好路径。对齐未签名的apkzipalignvp4myappunsigned。apkmyappunsignedaligned。apk使用你的私钥为apk签名apksignersignksmyreleasekey。jksoutmyapprelease。apkmyappunsignedaligned。apk验证apk是否已经被签名apksignerverifymyapprelease。apk基于加固Apk自动实现多渠道
关于多渠道打包,我们之前项目一直使用的是腾讯的VasDolly,故我们此次是采取VasDolly命令,但是需要先下载VasDolly。jar,至于放在什么位置没有要求,只需要gradle配置好路径即可,我直接是放在项目根目录。也可以使用360的多渠道加固,实际上整套都可以使用360加固提供的命令。
腾讯channel重新构建渠道包defreBuildChannel(){FilechannelFilefile({app〔channelPath〕}new)if(!channelFile。exists()){channelFile。mkdirs()}defcmdjavajar{app〔vasDollyPath〕}putc{channel。txt}{outputpackersApk()}{channelFile。absolutePath}printlncmdcmd。execute()。waitForProcessOutput(System。out,System。err)println‘packersexcuteVasDollyreBuildChannel’}敏感信息存取
我们都知道,签名需要签名文件,密码、别名等等文件,360加固需要配置账号与密码,这些都属于敏感信息,google官方不建议直接放在gradle中,它是以纯文本记录在gradle中的,建议存储在properties文件中。把敏感信息存放到自定义的properties文件中defpropertiesFilerootProject。file(release。properties)defpropertiesnewProperties()properties。load(newFileInputStream(propertiesFile))ext{签名配置signing〔keyAlias:properties〔‘RELEASEKEYALIAS’〕,keyPassword:properties〔‘RELEASEKEYPASSWORD’〕,storeFile:properties〔‘RELEASEKEYSTOREPATH’〕,storePassword:properties〔‘RELEASESTOREPASSWORD’〕〕app相关的配置app〔默认releaseapk的文件路径,因为加固是基于release包的releasePath:project。buildDiroutputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:{project。buildDir}outputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:project。buildDiroutputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:{project。buildDir}outputspackers,加固后进行腾讯多渠道打包的地址channelPath:{project。buildDir}outputschannels,腾讯VasDolly多渠道打包jar包地址vasDollyPath:VasDolly。jar〕360加固配置packers〔account:properties〔‘ACCOUNT360’〕,账号password:properties〔‘PASSWORD360’〕,密码zipPath:project。rootDirjiagu360jiagu。zip,加固压缩包路径unzipPath:{project。rootDir}jiagu360jiagu。zip,加固压缩包路径unzipPath:project。rootDirjiagu360jiagu。zip,加固压缩包路径unzipPath:{project。rootDir}jiagu360jiagubao,加固解压路径jarPath:project。rootDirjiagu360jiagubaojiagujiagu。jar,执行命令的jar包路径channelConfigPath:{project。rootDir}jiagu360jiagubaojiagujiagu。jar,执行命令的jar包路径channelConfigPath:project。rootDirjiagu360jiagubaojiagujiagu。jar,执行命令的jar包路径channelConfigPath:{project。rootDir}jiaguChannel。txt,加固多渠道jiagubaomac:https:down。360safe。com360Jiagu360jiagubaomac。zip,加固mac下载地址jiagubaowindows:https:down。360safe。com360Jiagu360jiagubaowindows64。zip加固widnows下载地址〕自动上传到服务器
这个功能准备在下篇文章更新,我们可以通过curl命令上传到自己的服务器,如果你在测试阶段可以上传到蒲公英或者fir。im托管平台,目前他们都提供了相关的操作方式,这样基本上整个自动化的目的就完成了,当然你也可以选择Jenknis自动化构建、打包及上传。
发布应用到fir。im托管平台入口方式一:firCLI命令行工具上传firppathtoapplicationTYOURFIRTOKEN
方式二:API上传通过curl命令调用相关的api1。获取凭证curlXPOSThttp:api。bq04。comappsHContentType:applicationjsond{type:android,bundleid:xx。x,apitoken:aa}
2。上传apkcurlFkeyxxxxxxFtokenxxxxxFfileaa。apkFx:nameaaaaFx:versiona。b。cFx:build1Fx:releasetypeAdhoctypeios使用Fx:changelogfirsthttps:up。qbox。me
发布应用到蒲公英入口curlFfiletmpexample。ipaFuKeyFapikeyhttps:upload。pgyer。comapiv1appupload
整体效果
我们的需求是需要打两批包,用于老后台与新后台,老后台的包必须加上app前缀,所以有三个任务packersNewRelease执行正常的加固打包用于新后台,packersOldRelease用于打包加前缀app名称用于老后台,packersRelease这个任务用于一键同时打包成老后台与新后台。
同时可以在gradle控制台查看打包任务的输出日志,如下:
gradle自动化源码
为了能够让大家尝试自动化gradle脚本带来的便利之处,下面我贡献上自己的整个gradle源码,需要的可以拿走去研究,如存在问题也希望多多交流。authorhuledate2020041513:42description:360自动加固Vaslloy多渠道打包把敏感信息存放到自定义的properties文件中defpropertiesFilerootProject。file(release。properties)defpropertiesnewProperties()properties。load(newFileInputStream(propertiesFile))ext{签名配置signing〔keyAlias:properties〔‘RELEASEKEYALIAS’〕,keyPassword:properties〔‘RELEASEKEYPASSWORD’〕,storeFile:properties〔‘RELEASEKEYSTOREPATH’〕,storePassword:properties〔‘RELEASESTOREPASSWORD’〕〕app相关的配置app〔默认releaseapk的文件路径,因为加固是基于release包的releasePath:project。buildDiroutputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:{project。buildDir}outputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:project。buildDiroutputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:{project。buildDir}outputspackers,加固后进行腾讯多渠道打包的地址channelPath:{project。buildDir}outputschannels,腾讯VasDolly多渠道打包jar包地址vasDollyPath:VasDolly。jar〕360加固配置packers〔account:properties〔‘ACCOUNT360’〕,账号认releaseapk的文件路径,因为加固是基于release包的releasePath:project。buildDiroutputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:{project。buildDir}outputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:project。buildDiroutputsapkrelease,对releaseapk加固后产生的加固apk地址packersPath:{project。buildDir}outputspackers,加固后进行腾讯多渠道打包的地址channelPath:{project。buildDir}outputschannels,腾讯VasDolly多渠道打包jar包地址vasDollyPath:VasDolly。jar〕360加固配置packers〔account:properties〔‘ACCOUNT360’〕,账号文末
以上步骤的前提是你需要配置好Gradle运行环境、熟悉Gradle的基本命令以及必要的耐心和不怕失败的勇气。
深入Android架构学习,可以私信我,发送核心笔记或手册,即可获取Android架构相关学习路线及相套的学习资料!