Android 插桩入门,腾讯 T2 大牛手把手教你
本文中的代码通过参考以下的文章和仓库来学习
完成一个简单的插件
本文设计到的代码都在这个项目中的 AsmPlugin 目录下代码
首先创建一个工程,这里是 AsmPlugin,我是在 PluginDemo 的工程下。因为我希望后面调试的时候,可以很容易的把这俩工程关联起来
AsmPlugin 是一个插件工程,是新建了一个 android 工程,然后根据 AndroidAutoTrack 里面的插件模板修改相应的 build.gradle 文件来完成的
在 AsmPlugin 中建立比较简单的插件模板,我引入了 AndroidAutoTrack 中的基类插件库,然后自己增加一个简单的 Demo
关联这个插件到 PluginDemo 中。
建立一个插件工程
我是建立一个普通的的 Android 工程,修改相应的文件完成插件的改造, 新建一个空的 Android 模块,这里是 SimplePlugin 修改模块中的 build.gradle 文件 插件的 gradle 文件如下
apply plugin: 'groovy'apply plugin: 'kotlin'apply plugin: 'java-gradle-plugin'apply plugin: 'kotlin-kapt'//apply from: '../upload_bintray.gradle'
dependencies {implementation gradleApi()implementation localGroovy()implementation project(":BasePlugin")implementation 'commons-io:commons-io:2.6'implementation 'org.javassist:javassist:3.27.0-GA'implementation 'com.google.auto.service:auto-service:1.0-rc6'kapt "com.google.auto.service:auto-service:1.0-rc6"}
gradlePlugin {plugins {version {// 在 app 模块需要通过 id 引用这个插件 id = 'simple-plugin'// 实现这个插件的类的路径 implementationClass = 'com.bn.simpleplugin.SimplePlugin'}}}
其中的 id 为插件的名称,跟引用这个插件时的名称对应
implementationClass 是指定插件入口类,需要实现 gradle 的 Plugin 类
文件结构如下
完
成简单的插件模块
增加两个类 SimplePlugin 类和 SimpleTransform 类 SimplePlugin.kt
class SimplePlugin : Plugin<Project> {override fun apply(p0: Project) {val appExtension = p0.extensions.getByType(AppExtension::class.java)appExtension.registerTransform(SimpleTransform(p0))}
}
SimpleTransform.kt
class SimpleTransform(private val project: Project):Transform() {override fun getName(): String {return "SimpleTransform"}
override fun getInputTypes(): Set<QualifiedContent.ContentType> {return TransformManager.CONTENT_JARS}
override fun getScopes(): MutableSet<in QualifiedContent.Scope>? {return TransformManager.SCOPE_FULL_PROJECT}
override fun isIncremental(): Boolean {return true}
@Throws(TransformException::class, InterruptedException::class, IOException::class)override fun transform(transformInvocation: TransformInvocation) {val injectHelper = AutoTrackHelper()val baseTransform = BaseTransform(transformInvocation, object : TransformCallBack {override fun process(className: String, classBytes: ByteArray?): ByteArray? {if(TestAsm.needHandle(className)){return TestAsm.handleTestClass3(classBytes!!)}if (ClassUtils.checkClassName(className)) {try {return injectHelper.modifyClass(classBytes!!)} catch (e: IOException) {e.printStackTrace()}}
return null}})baseTransform.startTransform()}
}
在 transform 方法中,我们可以拿到所有需要打包的类,根据自己的需要来完成插桩。
关联插件工程到主工程
修改主工程的根目录的 settings.gradle 文件,通过 includeBuild 关键字完成两个工程的关联,这个是为了方便后面定义的插件,能够去插件仓库中找到
修改主工程的根目录下的 build.gradle 文件。来完成插件定义
plugins {// 这个 id 就是在 versionPlugin 文件夹下 build.gradle 文件内定义的 idid "simple-plugin" apply false}
这个是为了声明插件
修改主模块的 build.gradle 文件,这里是 app/build.gradle,启用插件
评论