自定义Gradle插件,实现360加固
一、插件方式
1.1 插件代码实现
package com.study.jiagu_plugin
class Jiagu {
String userName;
String password;
String jiaguTools
String getUserName() {
return userName
}
void setUserName(String userName) {
this.userName = userName
}
String getPassword() {
return password
}
void setPassword(String password) {
this.password = password
}
String getJiaguTools() {
return jiaguTools
}
void setJiaguTools(String jiaguTools) {
this.jiaguTools = jiaguTools
}
}
package com.study.jiagu_plugin
import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApplicationVariant
import com.android.build.gradle.api.BaseVariantOutput
import com.android.builder.model.SigningConfig
import org.gradle.api.Plugin
import org.gradle.api.Project
/**
* 插件的实现需要继承Plugin
*/
class JiaguPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
//创建jiagu插件
Jiagu jiagu = project.extensions.create("jiagu", Jiagu)//Jiagu是Jiagu.class的简写
//回调,在gradle配置完成之后回调,在解析完build.gradle之后回调
project.afterEvaluate {
//因为app/build.gradle中与android{}闭包相关联的类时AppExtension
AppExtension android = project.extensions.android
//获取当前应用打包的变种
android.applicationVariants.all {
ApplicationVariant variant ->
//对应build.gradle中release/debug的签名配置信息
SigningConfig signingConfig = variant.signingConfig
variant.outputs.all {
BaseVariantOutput output ->
//apk输出的位置
File outputFile = output.outputFile
println "当前apk地址::${outputFile.getAbsolutePath()}"
//创建加固任务 jiag Debug capitalize()方法首字母大写
JiaguTask jiaguTask = project.tasks.create("jiagu${variant.baseName.capitalize()}", JiaguTask)
jiaguTask.jiagu = jiagu
jiaguTask.signingConfig = signingConfig
jiaguTask.apk = outputFile
}
}
}
}
}
package com.study.jiagu_plugin
import com.android.builder.model.SigningConfig
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
/**
* 加固的Task
*/
class JiaguTask extends DefaultTask {
Jiagu jiagu
SigningConfig signingConfig
File apk
JiaguTask() {
//用于在侧边栏归集任务
group = "jiagu"
}
@TaskAction
def run() {
//调用命令行工具
project.exec {
println "111Task::${apk.absolutePath}"
it.commandLine("java", "-jar", jiagu.jiaguTools, "-login", jiagu.userName, jiagu.password)
}
//如果有签名配置
if (signingConfig) {
project.exec {
println "222Task::${apk.absolutePath}"
//导入签名信息
it.commandLine("java", "-jar", jiagu.jiaguTools, "-importsign", signingConfig.storeFile.getAbsolutePath(),
signingConfig.storePassword, signingConfig.keyAlias, signingConfig.keyPassword)
}
}
//自动签名
project.exec {
println "333Task::${apk.absolutePath}"
// java -jar jiagu.jar -jiagu xxxx
it.commandLine("java", "-jar", jiagu.jiaguTools, "-jiagu", apk.absolutePath, apk.parent, "-autosign")
}
}
}
1.2 创建插件资源文件
资源文件的内容
implementation-class=com.study.jiagu_plugin.JiaguPlugin
1.4 将插件发布到本地仓库
插件Module下面的build.gradle文件源码如下所示://转化未groovy插件
apply plugin: 'groovy'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//build.gradle中所要用到的插件,开发在build.gradle中使用的插件时必须添加上这个工具
implementation 'com.android.tools.build:gradle:3.5.3'
//方便调用GradleApi
implementation gradleApi()
}
sourceCompatibility = "7"
targetCompatibility = "7"
//发布插件到本地仓库
apply plugin: 'maven-publish'
publishing {
publications {
Jiagu(MavenPublication) {
//要把源码生成的jar包上传
from components.java
groupId 'com.study'
artifactId 'jiagu'
version "1.0"
}
}
}
发布成功之后仓库所在路径如下所示:
C:\Users\{用户名}\.m2\repository\com\study\jiagu\1.0
1.5 插件运用的配置
在工程根目录build.gradle引入插件// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
mavenLocal()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//引入插件
classpath "com.study:jiagu:1.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
app/build.gradle中插件的运用
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//“com.study.jiagu”与jiagu_plugin/src/main/resources/META-INF/gradle-plugins/下面文件的名称
apply plugin:'com.study.jiagu'
jiagu{
username '360加固账号'
password '360加固密码'
jiaguTools 'D:\\jiagu\\start-package\\360jiagubao_windows_64\\jiagu\\jiagu.jar'
}
android {
signingConfigs {
release {
storeFile file('gradle_plugin.jks')
storePassword '123456'
keyPassword '123456'
keyAlias = 'GradlePlugin'
}
}
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.study.androidgradlestudydemo"
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
1.6 插件运用
二、脚本方式
import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApplicationVariant
import com.android.build.gradle.api.BaseVariantOutput
import com.android.builder.model.SigningConfig
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: JiaGuPlugin
jiagu {
username '360加固账号'
password '360加固密码'
jiaGuToolsPath 'D:\\jiagu\\start-package\\360jiagubao_windows_64\\jiagu\\jiagu.jar'
}
android {
signingConfigs {
release {
storeFile file('gradle_plugin.jks')
storePassword '123456'
keyAlias 'GradlePlugin'
keyPassword '123456'
}
}
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.study.gradlepluginbyscript"
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
class JiaGu {
String username
String password
String jiaGuToolsPath
String getUsername() {
return username
}
void setUsername(String username) {
this.username = username
}
String getPassword() {
return password
}
void setPassword(String password) {
this.password = password
}
String getJiaGuToolsPath() {
return jiaGuToolsPath
}
void setJiaGuToolsPath(String jiaGuToolsPath) {
this.jiaGuToolsPath = jiaGuToolsPath
}
}
class JiaGuPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
JiaGu jiagu = project.extensions.create("jiagu", JiaGu)
//回调,在gradle配置完成之后回调,在解析完build.gradle之后回调
project.afterEvaluate {
AppExtension android = project.extensions.android
android.applicationVariants.all {
ApplicationVariant variant ->
SigningConfig signingConfig = variant.signingConfig
variant.outputs.all {
BaseVariantOutput output ->
//输出的apk文件
File apk = output.outputFile
//创建加固任务
JiaGuTask jiaGuTask = project.tasks.create("jiagu${variant.baseName.capitalize()}", JiaGuTask)
jiaGuTask.jiaGu = jiagu
jiaGuTask.signingConfig = signingConfig
jiaGuTask.apk = apk
}
}
}
}
}
class JiaGuTask extends DefaultTask {
JiaGu jiaGu
SigningConfig signingConfig
File apk
JiaGuTask() {
//用于在侧边栏归集任务
group = "jiagu"
}
@TaskAction
def run() {
//调用命令行工具
project.exec {
// java -jar jiagu.jar -login user password
it.commandLine("java", "-jar", jiaGu.jiaGuToolsPath, "-login", jiaGu.username, jiaGu.password)
}
//非空即为true
if (signingConfig) {
project.exec {
// java -jar jiagu.jar -importsign xxxx
it.commandLine("java", "-jar", jiaGu.jiaGuToolsPath, "-importsign", signingConfig.storeFile.absolutePath,
signingConfig.storePassword, signingConfig.keyAlias, signingConfig.keyPassword)
}
}
project.exec {
// java -jar jiagu.jar -jiagu xxxx
it.commandLine("java", "-jar", jiaGu.jiaGuToolsPath, "-jiagu", apk.absolutePath,
apk.parent, "-autosign")
}
}
}
三、特殊目录buildSrc方式
buildSrc是AndroidStudio的特殊目录,使用这种方式可以不通过仓库做中介。build.gradle源码如下:
apply plugin: 'groovy'
repositories {
google()
jcenter()
}
dependencies {
implementation 'com.android.tools.build:gradle:3.5.3'
}
app/build.gradle源码如下:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
//apply plugin:JiaGuPlugin
apply plugin: 'com.study.jiagu'
jiagu {
username '360加固账号'
password '360加固密码'
jiaGuToolsPath 'D:\\jiagu\\start-package\\360jiagubao_windows_64\\jiagu\\jiagu.jar'
}
android {
signingConfigs {
release {
storeFile file('gradle_plugin.jks')
storePassword '123456'
keyAlias 'GradlePlugin'
keyPassword '123456'
}
}
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.study.gradlepluginbyscript"
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}