一。在as中新建module如下
image.pngapply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
//gradle sdk
compile gradleApi()
//groovy sdk
compile localGroovy()
compile "com.android.tools.build:gradle:$localBuildToolsVersion"
compile 'com.android.tools.build:transform-api:1.5.0'
compile 'org.aspectj:aspectjrt:1.8.10'
}
repositories {
mavenCentral()
}
//以上都为固定写法
//group和version
group='com.col.decypt_fixer'
version='1.0.0'
//打包到本地或者远程Maven库
uploadArchives {
repositories {
mavenDeployer {
//提交到远程服务器:
// repository(url: "http://www.xxx.com/repos") {
// authentication(userName: "admin", password: "admin")
// }
//本地的Maven地址设置为E:/Maven
repository(url: "file:../aop-tech/repositories")
}
}
}
com.col.decypt_fixer.properties里面的
implementation-class=com.col.decypt_fixer.LibChanger能跳转才说明结构正确。
插件作用,在transformNativeLibsWithStripDebugSymbolForApiTestRelease之后,packageApiTestRelease之前,替换.so库。
Task :app:transformNativeLibsWithStripDebugSymbolForApiTestRelease
Task :app:validateSigningApiTestRelease
Task :app:packageApiTestRelease
class LibChanger implements Plugin<Project> {
@Override
void apply(Project project) {
println("Plugin Start_________________________________________________________________")
if (project.plugins.hasPlugin(AppPlugin)) {
AppExtension android = project.extensions.getByType(AppExtension)
// android.registerTransform(new LibChangerTransform(project))
//创建一个Extension,名字叫做testCreatJavaConfig 里面可配置的属性参照MyPlguinTestClass
project.extensions.create("libChanger", MyPluginTestClass)
android.applicationVariants.all { variant -> //设置task依赖于生成BuildConfig的task,然后在生成BuildConfig后生成我们的类
//获取到scope,作用域
def variantData = variant.variantData
def scope = variantData.scope
//拿到build.gradle中创建的Extension的值
def config = project.extensions.getByName("libChanger")
println("Plugin Start______${variantData}______________${scope}_____________________________________________")
if (!variantData.toString().contains("ApiTestRelease")) return
// println("Plugin Start______${variant.getVariantData().getTaskName("transform", "release")}______________________________________________________")
//创建一个task
def createTaskName = scope.getTaskName("col", "LibChangerPlugin")
def createTask = project.task(createTaskName)
File debugSoFile = null
String outPath = null
def oriTask = project.tasks.getByName("transformNativeLibsWithStripDebugSymbolForApiTestRelease")
println("Plugin Start______${oriTask}______________________________________________________")
// println("Plugin Start______${oriTask.inputs}_________________________${oriTask.outputs}_____________________________")
oriTask.inputs.each { input ->
println("Plugin Start______input: ${input.properties}______________________________________________________")
}
oriTask.inputs.files.each { file ->
println("Plugin Start______input: ${file.absolutePath}______________________________________________________")
if (!file.absolutePath.endsWith("armeabi-v7a" + File.separator + "libjni-lib.so")) return
debugSoFile = file
}
oriTask.outputs.files.each { file ->
println("Plugin Start______output: ${file.absolutePath}______________________________________________________")
outPath = file.absolutePath
}
//设置task要执行的任务
createTask.doLast {
//生成java类
println("设置task要执行的任务_____________________________________________")
def lastIndexOf = outPath.indexOf("reader_sh_as")
println("lastIndexOf---------------------------------------- " + lastIndexOf)
if (lastIndexOf == -1) return
def rootPath = outPath.substring(0, lastIndexOf + "project_name".length() + 1)
println("rootPath---------------------------------------- " + rootPath)
debugSoFile = new File(rootPath + File.separator
+ "jni_lib" + File.separator
+ "libjni-lib_debug.so"
)
if (outPath == null || outPath.length() == 0) return
if (debugSoFile == null) return
def releaseSoFile = new File(outPath + File.separator
+ "0" + File.separator
+ "lib" + File.separator
+ "armeabi-v7a" + File.separator
+ "libjni-lib.so")
println("directoryInput---------------------------------------- " + debugSoFile.exists() + " " + releaseSoFile.exists())
if (!debugSoFile.exists() || !releaseSoFile.exists()) return
println(debugSoFile.absolutePath + " -------------------\n--------------------- " + releaseSoFile.absolutePath)
println(" ---------------------------------------- " + debugSoFile.exists() + " " + releaseSoFile.exists())
println(" ---------------------------------------- " + FileUtils.checksumCRC32(debugSoFile) + " " + FileUtils.checksumCRC32(releaseSoFile))
FileUtils.copyFile(debugSoFile, releaseSoFile)
println(" ---------------------------------------- " + FileUtils.checksumCRC32(debugSoFile) + " " + FileUtils.checksumCRC32(releaseSoFile))
}
if (oriTask) {
createTask.dependsOn oriTask
oriTask.finalizedBy createTask
}
}
}
}
}
class MyPluginTestClass {
def str = "默认值";
}
二。运行uploadArchives的gradle任务,会在配置的目录生成
image.png
三。引用
在project的根目录build.gradle引入
buildscript {
dependencies {
classpath 'com.col.decypt_fixer:decypt_fixer:1.0.0'
在需要调用插件的地方
apply plugin: 'com.android.application'
apply plugin: 'com.col.decypt_fixer'
四。编译时查看日志。
如果plugin的代码有问题,编译生成plugin时不会报错,宿主运行时会报错。
要先注释掉apply plugin: 'com.col.decypt_fixer'再修改运行uploadArchives
五。Transform插件
Transform API 是在1.5.0-beta1版开始使用,利用Transform API,第三方的插件可以在.class文件转为dex文件之前,对一些.class 文件进行处理。Transform API 简化了这个处理过程,而且使用起来很灵活。
注意getScopes和getReferencedScopes的区别
参考:
https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx
https://www.jianshu.com/p/811b0d0975ef
网友评论