专栏首页玩转全栈android自动化埋点了解一下
原创

android自动化埋点了解一下

埋点方案对比

1、手动在onClick等方法下粗鲁的➕埋点,嗯,是最最原始的一种方式了,没有比这个代码更加简洁的了,按需来加,缺点是,麻烦,得一个个加,漏掉没加,就只能等下一次了。

2、AOP方式

嗯,AOP是什么鬼,用简单的话来将,他就是面向切面编程的意思,可是面向切面编程又是什么鬼,在具体点就是,你能够将方法看成一个面,方法执行之前,执行过程中,执行之后就是一个一个的点,所谓的切点,就是这么来的。

因此,自动埋点就对于aop来说就小菜一碟啦,不仅如此,因为可以在方法前后打桩,所以,对方法做耗时统计也是小菜一碟,AOP通常需要通过配置注解来实现

AOP方式的特点是,埋点简单,一个注解就可以搞定,缺点还是不能自动,还是要你写代码,一个注解别看他简单,这也是代码啊。

3、asm的方式。

asm方式在粗的方面和aop方式对比的话,有点像,但是可以说更加底层,他能够做道对.class文件的修改,什么意思,就是说,分析.class文件,找到那些需要埋点的方法,比如,onclick,onlongclick等等,让后进行黑科技,一顿操作,加点字节码进去,重新编一个.class文件,替换之前的文件。

这种方式的特点就是,实现起来比较复杂,没那么容易玩的,好处就是,可以实现埋点自动化。

AndroidStudio上痛殴asm方式的原理

首先寄出这个apk打包的过程,图中,沃恩可以看到,.classfile会被打包成dex文件,你可以别以为dex文件就一个,可能有多个。

Google官方在Android Gradle的1.5.0 版本以后提供了 Transfrom API,这样一个接口给我们提供了一个可能,添加一个Transfrom的话,可以让我们对.class文件搞事了。

那么,我们需要关注的问题点有哪些:

1、需要对哪些.class文件进行处理,不可能都处理吧,肯定有些特点,怎么把这些文件拧出来。

2、拿到.class之后,怎么找到需要搞事的方法。

3、如和对搞事的方法搞事。

要实现上面这些东西,比较明朗的方式是,我们需要定义一个Gradle插件,下面就来给出解决以上三个问题的思路,首先,我们定义一个Transform,继承自com.android.build.api.transform.Transform

红框部分,解决了我们遇到的第一个问题,打包到dex中的文件其实有两种不同的组织方式,一种是jar,实际上也是一个.class的压缩包,其次是我们项目的,以文件夹的形式组织起来。

第二个问题,我们如何柠出我们需要处理的.class,这里其实需要我们定义一些规则,比如按照包名,来决定取舍,按照有无某内注解来决定是否需要对.class处理。

你比如:

if (className.contains('R$') ||
        className.contains('R2$') ||
        className.endsWith('R') ||
        className.endsWith('R2') ||
        className.endsWith('BuildConfig')) {
    return false
}

为了更加好用,你可以做成一种可以配置的方式。

第三个问题,.class找到了,要处理,我们如何来搞事,想一想,我们是要对.class字节码来修改的,这种操作我们可不是太擅长,那么,有没有那些工具可以呢,当然是有的,这个工具就是我们今天的主题ASM。

ASM框架中的核心类有以下几个:

  • ClassReader:该类用来解析编译过的class字节码文件。
  • ClassWriter:该类用来重新构建编译后的类,比如说修改类名、属性以及方法,甚至可以生成新的类的字节码文件。
  • ClassVisitor:主要负责 “拜访” 类成员信息。其中包括标记在类上的注解,类的构造方法,类的字段,类的方法,静态代码块。
  • AdviceAdapter实现了MethodVisitor接口,主要负责 “拜访” 方法的信息,用来进行具体的方法字节码操作

关于ASM框架更加具体的介绍请狂点这里; 我们首先来卡看ClassVisitor:

他暴露了给我们范文方法的接口,好,找到方法了,怎么在里面搞事呢?

答案是使用MethodVisitor,通过asm提供的这个接口,我们就可以把自己构造的字节码插入到需要打桩的方法中,基本操作大概是:

methodVisitor.visitMethodInsn(opcode, owner, methodName, methodDesc, false)

一个比较直观感受的对方法加代码的demo

工具的实现demo

顺着这个思路,笔者在luffy的基础上封装了一个更加容易体验的自动化埋点方式,感谢@JieYuShi

工具地址:Android_auto_track

工具包括两部分:插件,和库,插件实现基初功能,库的话,是将一些功能和接口暴露出来,想自己玩一把的话可以直接clone源码,体验。

参考资料

https://www.ibm.com/developerworks/cn/java/j-lo-asm30/index.html

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 打造秒级异常监控工具

    在一个迭代开发完毕之后,ci构建好测试包,交给测试人员进行测试,随后在测试的过程中,出现了一些问题,有些很容易追踪,比如一些逻辑bug,需求没有实现,但还是有一...

    brzhang
  • flutter接入现有的app详细介绍

    接入的方式,我是参考的官方的介绍文档,我这里尝试的是android的接入方式,还算比较顺利。

    brzhang
  • flutter插件开发需要了解的EventChannel与MethodChannel

    在flutter插件开发中,EventChannel与MethodChannel是两个不可避免的类。我们要了解它,最好先记住它通常用来干嘛。

    brzhang
  • JVM的简单实现

    felix
  • 【译】《Understanding ECMAScript6》- 第五章-Class

    目录 ES5中的拟Class结构 Class声明 Class表达式 存储器属性 静态成员 派生类 new.target 总结 自JavaScript面世以来,许...

    寒月十八
  • 深入分析Java反射(一)-核心类库和方法

    Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以...

    Throwable
  • javap查看class文件

    通过JVM编译java文件生成class字节码文件,很多时候很想用工具打开看看,目前还不清楚哪一个软件专门查看class文件的,但是通过windows下的jav...

    Jack Chen
  • 从头搭建一个在线聊天室(三)

    随着我们项目功能越来越多,把所有的逻辑代码都写在一个文件里已经不太合适了,下面就通过 flask 的工厂模式,把项目代码拆分开。

    周萝卜
  • jquery操作css相同class的节点

    平时的工作中有时候需要同时操作多个class相同的节点,这里使用jquery操作css相同class的节点。

    疯狂的技术宅
  • Android中的Proguard介绍

    ProGuard是一个Java Class文件的Shrinker,optimizer,obfuscator以及Preverifier。

    None_Ling

扫码关注云+社区

领取腾讯云代金券