每次都要手动使用工具去手动加固,非常麻烦,所以自己搞一个加固插件来提高生产力

开发环境使用的AGP7.0.2 ,相比较之前的版本,改动还是蛮大的,自己也踩了不少坑。

更多AGP7.0的内容可以关注一下虾哥的文章

掘金:https://juejin.cn/post/7056395437544046606

我们分为以下几步去完成:

  1. 获取apk产物
  2. 获取签名
  3. 获取加固工具
  4. 进行加固

获取APK

AGP7获取apk 的方式跟以前也大不相同了 ,我们需要借助Variant API apk 来进行获取

Variant API 是 Android Gradle 插件中的扩展机制,可以操纵各种选项,这些选项通常使用可影响 Android build 的 build 配置文件中的 DSL 进行设置。还可以通过 Variant API 访问 build 期间创建的中间工件和最终工件,例如类文件、合并后的清单或 APK/AAB 文件。

这里贴一下官方的示例

https://github.com/android/gradle-recipes/blob/agp-7.0/Kotlin/getApksTest/app/build.gradle.kts

AGP引入了 AndroidComponentsExtension ,可以为 finalizeDsl()beforeVariants()onVariants() 注册回调

  1. finalizeDsl:您可以通过此回调在 DSL 对象因组件(变体)创建而被锁定之前对其进行更改。VariantBuilder 对象是基于 DSL 对象中包含的数据创建的。
  2. beforeVariants此回调可通过 VariantBuilder影响系统会创建哪些组件以及所创建组件的部分属性。它还支持对 build 流程和生成的工件进行修改。
  3. onVariants:在此回调中,您可以访问已创建的 Variant 对象,您还可以为它们包含的 Property 值设置值或提供程序,以进行延迟计算。

在我们自定义的插件里面 获取到 AndroidComponentsExtension,通过 AndroidComponentsExtension 的onVariant回调注册 Task

        val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)androidComponents.onVariants {project.tasks.register<ApkTask>("${it.name}DisplayApks") {apkFolder.set(it.artifacts.get(SingleArtifact.APK))builtArtifactsLoader.set(it.artifacts.getBuiltArtifactsLoader())              }}

接下来看我们自定义的Task , 这些代码 在官方代码中都有实例

abstract class ApkTask : DefaultTask() {@get:InputFilesabstract val apkFolder: DirectoryProperty@get:Internalabstract val builtArtifactsLoader: Property<BuiltArtifactsLoader>@TaskActionfun taskAction() {val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get()) ?: throw RuntimeException("Cannot load APKs")builtArtifacts.elements.forEach {val apk = File(it.outputFile)}}
}

task的class 要是abstract 类型的,否则编译会提示final类型的错误。

获取签名

获取签名方面,我并没有在官方实例中找到资料,是在源码中发现了点踪迹。

先看下我们app下 build.gradle.kts中签名的配置

android {signingConfigs {create("release") {storeFile = file("enjoy.keystore")storePassword = "123456"keyAlias = "enjoy"keyPassword = "123456"}}
}

signingConfigs 是一个接口类型的,我们看下实现类:

多个实现类我们并不知道找哪个,接着往上一层看,下面的android 方法 的源码

fun org.gradle.api.Project.`android`(configure: Action<com.android.build.gradle.internal.dsl.BaseAppModuleExtension>): Unit =(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("android", configure)

可以看到它使用的是BaseAppModuleExtension,那我们获取到BaseAppModuleExtension 是不是就可以拿到签名了 ,在我尝试了一下果然可以 。

 val baseAppModuleExtension = project.extensions.getByType(BaseAppModuleExtension::class.java)val signingConfig = baseAppModuleExtension.signingConfigs.getByName("release")

这样就拿到了签名

获取加固工具

加固工具,我们是希望可以在app的gradle中可以动态配置 ,这里也是参考官方的方案:

https://github.com/gradle/kotlin-dsl-samples/blob/3c977388f7/samples/project-with-buildSrc/build.gradle.kts

先创建一个实体类,同样是要抽象类,需要的是工具地址,用户名和密码

abstract class JiaguExtension {abstract val jarPath: Property<String>abstract val username: Property<String>abstract val pwd: Property<String>
}

然后在插件中进行获取

val jiaguExtension  = project.extensions.create<JiaguExtension>("jiagu")

然后我们需要将配置信息传到task中进行加固任务。

进行加固

最后一步,我们开始进行加固 ,这里先介绍一下加固工具的使用:

  -login <username>           首次使用必须先登录 <360用户名><password>                <登录密码>-importsign <keystore_path>       导入签名信息 <密钥路径><keystore_password>            <密钥密码><alias>               <别名><alias_password>            <别名密码>-importmulpkg <mulpkg_filepath>       导入多渠道配置信息,txt格式-showsign             查看已配置的签名信息-showmulpkg               查看已配置的多渠道信息-deletemulpkg            清除已配置的多渠道信息-help                    显示帮助信息-config               配置加固可选项----------------------可选增强服务-------------------------------[-crashlog]               【崩溃日志分析】[-x86]                  【x86支持】[-analyse]               【加固数据分析】[-nocert]               【跳过签名校验】[-piracy]               【盗版监测】----------------------高级加固选项-------------------------------[-vmp]                 【全VMP保护】[-data]                 【本地数据文件保护】[-assets]             【资源文件保护】[-filecheck]                【文件完整性校验】[-ptrace]              【Ptrace防注入】[-so]                    【SO文件保护】[-dex2c]                【dex2C保护】[-string_obfus]                【字符串加密】[-dex_shadow]                【DexShadow】[-so_private]                【SO防盗用】[-double_check]              【双开检测】------------------------------------------------------------------config_so           配置需要加固的SO文件,以空格分隔-config_assets          配置需要忽略的资源文件,以空格分隔-config_so_private      配置防盗用的SO文件,以空格分隔-showconfig              显示已配置加固项-version                显示当前版本号-update                  升级到最新版本-jiagu <inputAPKpath>          加固命令 <APK路径><outputPath>                <输出路径>[-autosign]                 【自动签名】[-automulpkg]                 【自动多渠道】[-pkgparam mulpkg_filepath]      【自定义文件生成多渠道】

然后我们通过project提供的commandLine方法执行加固命令

 project.exec {登录 commandLine("java", "-jar", jiagu.jarPath.get(), "-login", jiagu.username.get(), jiagu.pwd.get())                配置签名         commandLine("java", "-jar", jiagu.jarPath.get(), "-importsign", signingConfig.storeFile?.absolutePath,signingConfig.storePassword, signingConfig.keyAlias, signingConfig.keyPassword)进行加固                          commandLine("java", "-jar", jiagu.jarPath.get(), "-jiagu", apk.absolutePath, apk.parent, "-autosign")
}

至此就完成了插件的加固功能。

使用

最后我们使用 maven-publish 插件推到本地进行引入使用

我们先需要在插件moudle的gradle中进行插件配置

gradlePlugin{plugins {register("jiaguPlugin") {id = "jiagu-plugin"implementationClass = "jiagu.JiaguPlugin"}}
}

这个id 是我们引入的时候所用的id,implementationClass 指向的是我们自定义的Plugin

最后我们发布到自己的本地仓库

group = "jiagu"
version = "1.0"
publishing {repositories {maven(url = "../repository")}
}

然后就是正常使用引入插件:

Project 的build.gradle.kts中:

 repositories {maven { url = uri("./repository/") }}classpath("jiagu:jiagu-plugin:1.0")

app 的build.gradle.kts中:

plugins {id("com.android.application")id("kotlin-android")id("jiagu-plugin")
}jiagu{jarPath.set("/Users/wyl/Downloads/360jiagubao_mac/jiagu/jiagu.jar")username.set("182XXXX0810")pwd.set("xiao")
}

最后可以看到在Gradle中看到加固插件已经存在了

最后看下效果:

其他

除此之外,如果想在assembleDebug或者 assembleDebug 中插入加固task,可以采用这种方案

   val apkProducer = project.tasks.register("apk${it.name}Task", ApkTask2::class.java)it.artifacts.use(apkProducer).wiredWithDirectories(ApkTask2::inputApk,ApkTask2::outputApk).toTransform(SingleArtifact.APK)
abstract class ApkTask2 : DefaultTask() {@get:InputDirectoryabstract val inputApk: DirectoryProperty@get:OutputDirectoriesabstract val outputApk: DirectoryProperty@TaskActionfun taskAction() {val apks = File(inputApk.get().toString())apks.listFiles()?.forEach {if (it.name.endsWith(".apk")) {val outPutFile = File(outputApk.get().toString() + "/out.apk")//执行加固任务}}}
}

这样每次执行assembleDebug或者 assembleDebug 任务的时候都会进行apk的加固。

结尾

至此完结撒花。

地址:https://github.com/WngYilei/Jiagu

欢迎大家一起交流分享,提出宝贵意见。

参考:

虾哥:https://juejin.cn/post/7056395437544046606

官方文档:https://github.com/gradle/kotlin-dsl-samples

官方文档:https://github.com/android/gradle-recipes

官方文档:https://developer.android.google.cn/studio/build/extend-agp?hl=zh_cn

AGP7.0|kts 搞一个加固插件相关推荐

  1. 自己动手搞一个tip 插件

    由于最近做工作站需要悬浮tip 插件,找来找去没有一个适合我的,于是自己动手搞一个! <!DOCTYPE html> <html><head><meta ch ...

  2. 从0开始搞一个锦鲤游动——动起来

    上一篇文章主要讲了如何绘制一条锦鲤,而今天这篇文章,就讲如何让我们的锦鲤动起来.这次需要写一些比较复杂的算法,与数学关系很大,个别地方可能难以理解.不过大家可以多看两遍仔细斟酌,如果还是不理解的话可以 ...

  3. 从0开始搞一个锦鲤游动——画锦鲤

    首先大家可以看一下这个鱼的图案 一.前期准备 1.新建一个项目 2.将MainActivity的XML文件写成 <?xml version="1.0" encoding=&q ...

  4. 我写的第一个jquery插件:jquery.photoFrame(version 0.2)

    先看效果 introduce     jQuery photoframe plugin     A useful plugin to beautify image or text by wrappin ...

  5. 前端每周清单第 52 期: Webpack 4.0,GraphQL 安全加固,去中心化的 Web

    作者:王下邀月熊 编辑:徐川 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点:分为新闻热点.开发教程.工程实践.深度阅读.开源项目.巅峰人生等栏目.欢迎关注[前端之巅 ...

  6. 从 0 开始搭建一个技术博客,私藏干货~

    2019独角兽企业重金招聘Python工程师标准>>> 技术博客的选型有很多种,如:博客园.CSDN.开源中国.简书.知乎等--都可以用来写文章,形成自己的技术博客. 上面的博客都是 ...

  7. 实现你人生中的第一个jQuery插件

    前言 本想把本篇取名:从0开始写前端UI框架:实现你人生中的第一个jQuery插件 ,但感觉标题太长,所以简单明了直接取后面主题为题目吧. 前一篇文章 已经对my-ui框架做了简单的介绍.谈到了我是如 ...

  8. ASP.NET2.0轻松搞定统计图表【月儿原创】

    ASP.NET2.0轻松搞定统计图表 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/           时间:2007.3.27 本文讲述如何绘制条形图,折线图, ...

  9. 插件制作教程 php,typecho插件编写教程(二):写一个新插件

    第一节我们了解了一个插件的基本构成,下面我们需要一个实例练习巩固. 真赶巧,老高最近正在改版百度sitemap提交插件for typecho,下面和老高一起改版吧! 准备 不知道大家用过WP版的百度结 ...

最新文章

  1. HTTP服务器端常用推送技术
  2. 用脚本批量执行redis命令
  3. Ninja Blocks物联网平台简介
  4. ai模仿声音软件_如何开发人工智能类的软件?人工智能让我们的生活更加便捷!...
  5. one-to-many many-to-one 为什么只生成了一张表呢?
  6. 【译】Getting Started With Ethereum and Building Basic Dapp — Part 1
  7. vue render函数
  8. 右边菜单_AI基础教程65:使用文字菜单编辑文字(七)查找字体
  9. 重磅资料!Github上的PHP资源汇总大全
  10. 30余种加密编码类型的密文特征分析
  11. saefetchurl java_新浪云sae给的图片操作类
  12. Hadoop资源调度器
  13. java斗地主发牌源码
  14. Go基础系列:Go实现工作池的两种方式(一)
  15. 微软Exchange Server 2010 SP1下载
  16. 扇贝python多少钱_扇贝多少钱一斤?扇贝多少钱一斤2017?
  17. 像京东等大厂为什么不通过减薪来代替裁员,降低成本?
  18. Windows 开启护眼模式 | Windows护眼软件
  19. 存储器电路设计学习记录之 buffer提高驱动能力/带负载能力
  20. 3dmax制作光束效果教程!

热门文章

  1. 267. 使用Spinnaker结合Jenkins持续构建
  2. 隐私计算FATE-核心概念与单机部署
  3. 如何禁止访问某个网站
  4. 微信 html 字体 自动换行,详解微信小程序-canvas绘制文字实现自动换行
  5. Redis 面霸绝杀:连环五十二问!三万字 + 八十图详解!
  6. FocusLab新生大礼包之:一些常用的Linux命令教程
  7. 显卡低对整个计算机的影响,显卡的大小对电脑的影响
  8. ​LeetCode刷题实战50:Pow(x, n)
  9. 【报复性赚钱】2023年5大风口行业
  10. ubuntu引导删除+win10引导修复