一、插件开发方式和配置
1、Build Script
插件写在build.gradle中,适用简单功能
class ExtensionBean {
String message = null
}
class TestPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.extensions.create('e', ExtensionBean)
project.task('test') << {
println 'msg:' + project['e'].message
}
}
}
apply plugin: TestPlugin
e {
message = 'hello world'
}
2、buildSrc项目
源码放在rootProjectDir/buildSrc/src/main/groovy,只对项目可见
3、独立项目
- 目录结构
|- build.gradle
|-src
|-main
|-groovy
|-包名
|-resources
|-META-INF
|-gradle-plugins
|-插件名.properties
- build.gradle
// 本地发布
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
implementation gradleApi()
implementation localGroovy()
implementation 'org.javassist:javassist:3.25.0-GA'
implementation 'com.android.tools.build:gradle:3.4.2'
}
repositories {
mavenCentral()
}
group = "..."
version = "1.0.0"
uploadArchives{
repositories {
// 本地发布
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
- 插件名.properties
implementation-class=包名.插件实现类
- 项目添加依赖
buildscript {
repositories {
//本地依赖
maven{url uri('repo')}
}
dependencies {
...
classpath 'groupId:modulename:version'
}
}
二、java字节码
jvm主要结构
- 类加载系统(class loader)
- 运行时数据区
- 栈(java stack)
- 局部变量区
- 操作数栈
- 帧数据区
- 本地方法栈(native method stack)
- PC寄存器/程序计数器(Program Count Register)
- 方法区(Method Area)
- 堆(Heap)
- 栈(java stack)
- 执行引擎
栈帧
Java栈和线程关联,创建线程会创建对应Java栈。java栈包含多个栈帧(Stack Frame),栈帧和每个方法关联。每运行一个方法,就创建一个栈帧。
三、ASM
ASM3.0编程框架
ClassReader :用于获取字节码数据,分析字节码,构建抽象树在内存中表示字节码
ClassVisitor :接口用于访问visit事件
ClassAdaptor:实现ClassVistor接口,通过职责链访问下一个Visitor,派生类可以封单一功能修改字节码文件
ClassWriter:实现ClassVisitor接口,是字节码生成工具,用于将生成的字节码的字节流,写回文件产生调整后的class文件
javaassit与ASM差异
相似: javaassist和ASM都是字节码编辑工具,都可以编辑操作字节码
区别: javaassit使用难度较低,以类似于java代码的方式植入 ASM需要一定java字节码基础
intellj下如何快速使用ASM开发
装个ASM插件,翻译一下,然后再用插件根据翻译代码去写实现即可
注意,插件需要build一下,才能翻译
四、gradle 插件调试
#方法一
#执行gradle命令,附加参数
#-Dorg.gradle.debug=true --no-daemon
./gradlew app:assembleDebug -Dorg.gradle.debug=true --no-daemon
#此时命令行会等待用户调试
#这个时候选择configuration=》新建Remote调试=》确认 =》然后点击调试按钮即可
#方法二
export GRADLE_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
#然后每次gradle执行都可以调试了