第04讲:编译插桩操纵字节码,实现不可能完成的任务

发布时间:2023-04-12 15:00

相信做过 Android 开发的工程师大多都遇到过这种需求:

记录每一个页面的打开和关闭事件,并通过各种 DataTracking 的框架上传到服务器,用来日后做数据分析。

面对这样的需求,一般人都会想到,这其实就是在每一个 Activity 的 onCreate 和 onDestroy 方法中,分别添加页面打开和页面关闭的逻辑。常见的做法有以下两种:

  1. 修改项目中现有的每一个 Activity,这样显然不够高大上,并且如果项目以后需要添加新的页面,这套逻辑需要重新拷贝一遍,非常容易遗漏。
  2. 将项目中所有的 Activity 继承自 BaseActivity,将页面打开和关闭的逻辑添加在 BaseActivity中,这种方案看起来比第 1 种方案高级得多,并且后续项目中有新的 Activity,直接继承 BaseActivity 即可。但是这种方案对第三方依赖库中的界面则无能为力,因为我们没有第三方依赖库的源码。

就是在这种环境下,一种更加优雅更加完整的方案应运而生:编译插桩。

编译插桩是什么

顾名思义,所谓编译插桩就是在代码编译期间修改已有的代码或者生成新代码。实际上,我们项目中经常用到的 Dagger、ButterKnife 甚至是 Kotlin 语言,它们都用到了编译插桩的技术。

理解编译插桩之前,需要先回顾一下 Android 项目中 .java 文件的编译过程:

第04讲:编译插桩操纵字节码,实现不可能完成的任务_第1张图片
从上图可以看出,我们可以在 1、2 两处对代码进行改造。

  1. 在 .java 文件编译成 .class 文件时,APT、AndroidAnnotation 等就是在此处触发代码生成。
  2. 在 .class 文件进一步优化成 .dex 文件时,也就是直接操作字节码文件,也是本课时主要介绍的内容。这种方式功能更加强大,应用场景也更多。但是门槛比较高,需要对字节码有一定的理解。

本课时主要介绍第 2 种实现方式,用一张图来描述如下过程,其中红色虚框包含了本课时要讲的所有内容。

第04讲:编译插桩操纵字节码,实现不可能完成的任务_第2张图片
一般情况下,我们经常会使用编译插桩实现如下几种功能:

  • 日志埋点;
  • 性能监控;
  • 动态权限控制;
  • 业务逻辑跳转时,校验是否已经登录;
  • 甚至是代码调试等。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号