吐泡泡的阿呆 android Dev Engineer

【笔记】android-自动化字节码插桩

2019-08-22
adai

一、插件开发方式和配置

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、独立项目

writing-gradle-plugin

  • 目录结构
|- 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栈和线程关联,创建线程会创建对应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插件调试方法

#方法一
#执行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执行都可以调试了

五、基于ASM和gradle plugin实现的简单自动化日志库

pandawatcher

ref


Similar Posts

Comments