APT和AOP在android那些事情

APT和AOP在android那些事情

业务背景

apt

你们对eventbus应该不会陌生吧,eventbus是一个很是优秀的事件总线框架,在设计模式中,有点相似观察者模式,只不过一个升级版本的观察者模式,而且发送跟接收是切割的,解决不少让人头疼的内存泄漏问。其中eventbus所用到的技术就是apt,若是你们在项目中有使用到观察者模式,不妨用eventbus来改善一下。java

aop

想象一个业务场景,业务要统计activity的启动耗时,也就是oncreate,onstart这些生命周期方法的耗时,一种原始的方式就是在每一个activity的生命周期中添加剧复的代码,好比:android

@Override
    protected void onCreate(Bundle savedInstanceState) {
        long start=System.currentTimeMillis();
        super.onCreate(savedInstanceState);  //1
        setContentView(R.layout.activity_main);
        long spend=System.currentTimeMillis()-start; //2
    }
复制代码

想一想一个activity那么多生命周期,一个android项目那么多activity,是否是很繁琐呢。这时候aop就出场了,为何不用谷歌亲儿子apt呢,由于apt一个比较大的局限性是:没法在当前类添加删除代码,只能建立一个新的类。简单点归纳就是aop是一个比apt更强大的代码生成框架。编程

简介

  • APT:(Annotation Processing Tool)即注解处理器,是一种注解处理的工具,用来在编译器扫描以及处理注解。以注解做为桥梁,经过预先设定好的代码规则来生成对应的Java代码
  • AOP:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程。因此这里所表明的实际上是一种思想,实现这个思想的技术有:ASPECTJ,ASM,JAVASIST,主要是这三个派系
    ## 对比
能力 APT AOP
建立新类 y y
修改当前类 n y
实现技术 AutoService ASPECTJ,ASM,JAVASIST
注解 y y
sdk代码修改 n y

android打包流程

android官方文档
build-process_2x设计模式

上一张图中,compilers阶段实际上是有不少个transform组成的
4821599-9f88c2f9936af805bash

其中apt,aop都是做用于compilers阶段apt做用于class -->.dex阶段,aop做用于class-->.dex或者jar-->.dex阶段。能够进一步看到aop更增强大网络

使用小建议

apt,aop虽然可以减小不少重复代码量,代码结构优化,可是也看出来了,没有源代码,不利于排查问题,因此使用者必定要克制,不是这两个技术很黑科技就喜欢去使用,不然就是给本身的项目埋下风险。同窗编写这些apt,aop代码的同窗必定要留够足够的调试信息,方便后续的问题追踪框架

细讲apt

其实网络上已经有不少优秀apt的案例,就不想重复的编写这个demo.贴一个推荐的案例
apt案例ide

细讲aop

asm实现

用来动态生成类或者加强既有类的功能,ASM是能够直接产生二进制 class 文件,也能够在类被加载入 Java 虚拟机以前动态改变类行为,底层字节码框架,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有必定的了解。工具

整体思路讲解post

  • 注册transform,接收编译阶段代码的输入,这里主要有class和jar包
  • 使用java的jarfile接口解析jar包,而且得到jar包里面的class文件
JarFile jarFile = new JarFile(inFile)
  Enumeration<JarEntry> entries = jarFile.entries()
复制代码
  • 使用asm借口解析jar包里面的class,更改本身想要的代码操做,建议使用asm5版本,gradle默认会有这个sdk,无需集成,示例:
ClassReader reader = new ClassReader(entryBytes)
ClassWriter classWriter = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = new MyClassVisitor(classWriter)
复制代码
  • 不管更改与否jar包或者class,都要将文件拷贝到下一个输入位置,参考示例:
File outFile = transformInvocation.outputProvider.getContentLocation(
                                    jarInput.file.absolutePath,
                                    jarInput.contentTypes,
                                    jarInput.scopes,
                                    Format.JAR)
FileUtils.copyFile(jarInput.file, outFile)
复制代码

网上有一个很是好的讲解,而且有示例源码:
案例

aspectj实现

aspectj是经过注解来实现aop的切面方案,也是最容易上手的一个方案
案例

javassit实现

案例

总结

上面的讲究都是引用了其余人的讲解成果,后面会输出我的编写demo的文章,更加细致的讲解aop这块,固然估计可能没有我如今所引用的案例优秀,透彻。

但愿个人文字能给你带来帮助,同时也欢迎关注我的公众号,个人全部文章第一手信息回优先发布这里。我的公众号:河边的小黑屋

相关文章
相关标签/搜索