平时的打包测试中,我们会使用到360加固保来手动对apk进行签名和加固,比较繁琐。今天本篇实战讲解如何使用gradle插件化实现360自动加固,一键彻底解放双手。
插件的编写
-
1 首先到官网https://jiagu.360.cn下载加固包,这里面的jiagu.jar文件后面会用到,还有里面有一些说明性的文本内容可以阅读一下,帮助使用。
-
2 编写插件有三种方式,我们选择创建一个java-library的module,来编写我们的插件,在main目录下创建一个如图所示的文件,文件夹的路径和名称除了红框中的内容可以自由改变,但是其它的地方保持一致,这里我们创建了一个名字为
com.oman.plugin.properties
的文件,内容是我们要实现的插件com.oman.plugin.AutoJiaguPlugin
。
-
3 想要实现一个插件,需要继承
org.gradle.api.Plugin
,但是我们首先要依赖这个类所在的库,如下:apply plugin: 'java-library' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation gradleApi() //Plugin类所在的库 implementation 'com.android.tools.build:gradle:3.6.3' }
-
4 自定义一个Model用来存储360加固需要的用户名,密码,签名的相关信息等,这里一定要设置set和get方法,不然在后面配置使用的时候会报错。源码如下:
public class ConfigModel { private String userName; private String userPassword; private String keyStorePath; private String keyStorePassword; private String keyAlias; private String keyAliasPassword; private String jarToolsPath; public void setUserName(String userName) { this.userName = userName; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public void setKeyStorePath(String keyStorePath) { this.keyStorePath = keyStorePath; } public void setKeyStorePassword(String keyStorePassword) { this.keyStorePassword = keyStorePassword; } public void setKeyAlias(String keyAlias) { this.keyAlias = keyAlias; } public void setKeyAliasPassword(String keyAliasPassword) { this.keyAliasPassword = keyAliasPassword; } public void setJarToolsPath(String jarToolsPath) { this.jarToolsPath = jarToolsPath; } public String getUserName() { return userName; } public String getUserPassword() { return userPassword; } public String getKeyStorePath() { return keyStorePath; } public String getKeyStorePassword() { return keyStorePassword; } public String getKeyAlias() { return keyAlias; } public String getKeyAliasPassword() { return keyAliasPassword; } public String getJarToolsPath() { return jarToolsPath; } }
-
5 自定义插件实现Plugin接口,
.all
相当于遍历。如果对于gradle比较熟悉的同学,这里应该不是什么问题,不熟悉的同学,可以将回调中的每一个对象的属性值打印出来就清楚了。public class AutoJiaguPlugin implements Plugin<Project> { @Override public void apply(Project project) { /** * auto 是为了在使用的时候配置的 * ConfigModel 是一个包含了配置信息的类 * 这样我们就可以得到app中的配置信息 */ ConfigModel model = project.getExtensions().create("auto", ConfigModel.class); project.afterEvaluate(new Action<Project>() { @Override public void execute(Project project) { /** * 下列操作是为了获取我们需要加固的apk的文件,并将apk文件和配置信息传递给真正的task */ AppExtension appExtension = project.getExtensions().getByType(AppExtension.class); appExtension.getApplicationVariants().all(new Action<ApplicationVariant>() { @Override public void execute(ApplicationVariant applicationVariant) { applicationVariant.getOutputs().all(new Action<BaseVariantOutput>() { @Override public void execute(BaseVariantOutput variantOutput) { File outputFile = variantOutput.getOutputFile(); String name = variantOutput.getName(); if ("release".equals(name)) { project.getTasks().create("autoJiagu", AutoJiaguTask.class, outputFile, model); } } }); } }); } }); } }
-
6 上面有一个
AutoJiaguTask
类,实现了DefaultTask,这个是真正执行任务的Task,task内部根据传进来的需要加固的apk和配置信息,执行相关的登录,签名和加固操作,源码如下:public class AutoJiaguTask extends DefaultTask { private final File mApk; private final ConfigModel mConfigModel; @Inject public AutoJiaguTask(File apk, ConfigModel jiaguExt) { setGroup("jiagu"); this.mApk = apk; this.mConfigModel = jiaguExt; } @TaskAction public void jiaguAction() { //360加固 登录 getProject().exec(new Action<ExecSpec>() { @Override public void execute(ExecSpec execSpec) { //具体的命令在 360jiagubao_windows_64\jiagu\help.txt中有 execSpec.commandLine("java", "-jar", mConfigModel.getJarToolsPath(), "-login", mConfigModel.getUserName(), mConfigModel.getUserPassword()); } }); //签名 getProject().exec(new Action<ExecSpec>() { @Override public void execute(ExecSpec execSpec) { execSpec.commandLine("java", "-jar", mConfigModel.getJarToolsPath(), "-importsign", mConfigModel.getKeyStorePath(), mConfigModel.getKeyStorePassword(), mConfigModel.getKeyAlias(), mConfigModel.getKeyAliasPassword()); } }); //加固 getProject().exec(new Action<ExecSpec>() { @Override public void execute(ExecSpec execSpec) { execSpec.commandLine("java", "-jar", mConfigModel.getJarToolsPath(), "-jiagu", mApk.getAbsolutePath(), mApk.getParent(), "-autosign"); } }); } }
-
7 其实360加固中已经为我们提供了详细的信息来使用这些api:
-
8 写完插件后,我们编写插件的版本信息到build.gradle文件中。
apply plugin: 'java-library' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation gradleApi() implementation 'com.android.tools.build:gradle:3.6.3' } sourceCompatibility = "8" targetCompatibility = "8" //将插件发布到本地 apply plugin: 'maven-publish' publishing { publications { AutoJiaguPlugin(MavenPublication) { from components.java groupId 'com.oman' artifactId 'jiagu' version '1.0' } } }
-
9 双击图中红框的任务,将插件发布到本地:
插件的使用
- 1 首先在项目的build.gradle文件中声明本地仓库
mavenLocal()
和添加classpath,classpath的内容要和发布的时候填写的内容一致,不然找不到插件,如下:
- 2 在app的build.gradle文件中使用插件
apply plugin: 'com.oman.plugin'
,这个值要和我们在上面插件的编写
第二步中的值保持一致,并且配置信息。这里的auto
还记得是怎么来的吗?对,就是在上面第五步中创建声明的,将用户信息和签名信息配置好。
- 3 这时候同步项目,在右侧就会出现一个
jiagu
的分类,分类中有一个任务autoJiagu
。这两个属性值都是在上面定义的(setGroup("jiagu")
和project.getTasks().create("autoJiagu"
)。
- 4 这时候我们先生成一个未签名的apk,如图所示:
- 5 这时候双击步骤3的
autoJiagu
按钮,就会开始执行我们AutoJiaguTask
中的逻辑,进行登录,签名和加固,最终生成了一个新的apk,如图所示:
总结
gradle插件化在工作中可以减轻手动重复的工作,解放我们的双手。本文中仅仅演示了部分功能,其实还有很多功能按照相同的模式,就可以实现,本文就不赘述了,读者自行查看。