Skip to content

Android字节码插件,编译期间动态修改代码,改造添加全埋点日志采集功能模块,对常见控件进行监听处理

Notifications You must be signed in to change notification settings

zhangpengchengN1/Luffy

Repository files navigation

Luffy

Android字节码插件,编译期间动态修改代码 先打包一下插件到本地仓库进行引用,在项目的根build.gradle加入插件的依赖

dependencies {
    classpath 'com.xixi.plugin:plugin:1.0.1-SNAPSHOT'
}

在app的build.gradle中

apply plugin: 'apk.move.plugin'

xiaoqingwa{
    name = "小傻逼"
    isDebug = true
    //具体配置
    matchData = [
            //是否使用注解来找对应方法
            'isAnotation': false,
            //方法的匹配,可以通过类名或者实现的接口名匹配
            'ClassFilter': [
                    ['ClassName': 'com.xishuang.plugintest.MainActivity', 'InterfaceName': 'android/view/View$OnClickListener',
                     'MethodName':'onClick', 'MethodDes':'(Landroid/view/View;)V']
            ],
            //插入的字节码,方法的执行顺序visitAnnotation->onMethodEnter->onMethodExit
            'MethodVisitor':{
                MethodVisitor methodVisitor, int access, String name, String desc ->
                    MethodVisitor adapter = new AutoMethodVisitor(methodVisitor, access, name, desc) {
                        boolean isAnnotation = false
                        @Override
                        protected void onMethodEnter() {
                            super.onMethodEnter()
                            //使用注解找对应方法的时候得加这个判断
//                            if (!isAnnotation){
//                                return
//                            }

                            methodVisitor.visitMethodInsn(INVOKESTATIC, "com/xishuang/plugintest/MainActivity", "notifyInsert", "()V", false)
                            methodVisitor.visitLdcInsn(name)
                            methodVisitor.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false)
                            methodVisitor.visitMethodInsn(INVOKESTATIC, "com/xishuang/plugintest/TimeCache", "setStartTime", "(Ljava/lang/String;J)V", false)
                        }

                        @Override
                        protected void onMethodExit(int opcode) {
                            super.onMethodExit(opcode)
                            //使用注解找对应方法的时候得加这个判断
//                            if (!isAnnotation){
//                                return
//                            }

                            methodVisitor.visitLdcInsn(name)
                            methodVisitor.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false)
                            methodVisitor.visitMethodInsn(INVOKESTATIC, "com/xishuang/plugintest/TimeCache", "setEndTime", "(Ljava/lang/String;J)V", false)
                            methodVisitor.visitLdcInsn("耗时")
                            methodVisitor.visitLdcInsn(name)
                            methodVisitor.visitMethodInsn(INVOKESTATIC, "com/xishuang/plugintest/TimeCache", "getCostTime", "(Ljava/lang/String;)Ljava/lang/String;", false)
                            methodVisitor.visitMethodInsn(INVOKESTATIC, "android/util/Log", "d", "(Ljava/lang/String;Ljava/lang/String;)I", false)
                        }

                        /**
                         * 需要通过注解的方式加字节码才会重写这个方法来进行条件过滤
                         */
                        @Override
                        AnnotationVisitor visitAnnotation(String des, boolean visible) {
//                            if (des.equals("Lcom/xishuang/annotation/AutoCount;")) {
//                                println "注解匹配:" + des
//                                isAnnotation = true
//                            }
                            return super.visitAnnotation(des, visible)
                        }
                    }
                    return adapter
            }
    ]
}

要是使用演示的话,因为还没上传到jcenter库,所以只能本地仓库打包插件,记得要先把依赖都注释掉,插件打包完成后再启用,不然会编译不过去的。

About

Android字节码插件,编译期间动态修改代码,改造添加全埋点日志采集功能模块,对常见控件进行监听处理

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 61.8%
  • Groovy 38.2%