本文同步自wing的地方酒馆

最近博客更新越来越慢了,有两方面原因:

1.没啥好写的。

2.应该沉下心好好沉淀自己,积累一些东西,博客写的太频繁有”刷博客“之嫌,还容易浮躁。

浮躁是大忌 ,所以还是沉下心好好学吧。

网上已经有了很多类似的文章,这里再写一次是为了自己当做笔记,主要是对APT,AspectJ、Javassist的简单实用进行记录,方便以后翻阅。

AOP是什么这里不多作解释了,个人理解总结下来就是相对于各个垂直深入的业务逻辑,每个业务逻辑深度的某个层面他们有需要共同的特征,此时对这种特征进行统一的处理,也就是所谓的AOP(欢迎拍砖哈,技术在讨论中提升)

主要应用场景:

  • 权限检查
  • 日志记录
  • 性能监控
  • 埋点操作

Android 下一些可以进行AOP的工具

APT

在编译时生成 .java 文件。

代表作品 ButterKnife 、 DataBinding、 EventBus3、Dagger2 等。

AspectJ

在.java编译为.class的时候,进行代码注入。

代表作品: Hugo

Javassist

对已经编译好的class文件进行操作。

代表作品: 各类热修复框架(为了解决类校验问题)。

各个工具操作时机图

这里盗一张图。原图地址:http://www.jianshu.com/p/dca3e2c8608a

具体用法

APT

APT是编译时生成代码的技术, 主要用到了注解 以及处理注解的Process

这里我写一个简单的小例子,来展示如何使用APT,这个例子类似于MVPHelper的功能,但其实是没有什么乱用的,只是展示而已。

  • 建立一个module 用于声明注解。



这里Contract注解,是为了标注一个Activity需要使用MVP模式。并且需要自动生成MVP代码。

  • 再建立另一个module 用于处理这些注解。

注意这里必须是java库,也就是说gradle要apply java 插件,否则将引用不到javax包下的内容。

这个时候,我们只需要让ConrtactProcessor 继承 AbstractProcess,并且实现process函数去处理这个注解即可。

这里生成代码使用了Javapoet, 我们的目标是在Activity上面使用@Contract注解自动生成MVP代码,并且@Inject自动注入presenter,如下图:



这些红掉的代码,就是我们想要利用APT生成的代码,@Inject 用于表示注入mPresenter,这样就不用我们自己new了,当然这里是最简单的注入展示。 我们反过来想想,想让这些代码可以工作,生成的代码应该是怎样的。生成的代码路径如下所示:

MVP部分的代码不多说,来说一说presenter是如何注入的,其实很简单:



结合上面红色的代码看,应该会一目了然吧。

关于如何生成代码,只需要在process方法中使用javapoet即可,代码比较简单繁琐,这里就不贴了,有需要的可以到文章尾部的链接查看代码。

AspetJ

AspetJ的引入比较简单,主要是沪江公司对AspetJ进行了一些Android方面的适配。

在gradle添加

classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.10'

以及

apply plugin: 'android-aspectjx'

使用的时候,只需要新建一个类,并且使用@Aspect注解,即可对需要hook的类生效,并且无需直接使用。

因为在看这个之前有在用Xposed,所以感觉两个很像,上手很快。

我们将要使用这个工具实现Activity 启动时间的监控,以及登录权限管理的注入,以往判断用户登录往往需要每个函数都判断一下最后执行逻辑,其实这完全可以注入进去,就像”切面“所说,需要登录的地方,一刀切。

实现Activity启动时间监控,这里写简单一点,单纯的从onCreate开始到onResume结束进行计时操作。

另外一个是登录检验操作,我们理想的事情是给一个函数添加一个注解,并且这个注解来判断是否登录执行相应的转跳提示操作。

示意如下,比如onResume需要判断是否登录,只需要一个注解

我们把需要的逻辑判断写在@AspetJ 注解的类里即可。

这样不管是埋点还是性能监控还是登录权限检验,都可以异常方便的执行。再也不像原先那样麻烦了。

Javassist

这个需要结合自定义gradle plugin一起操作,大家都知道apk编译的时候,先把java编译为class文件,接下来会变为dex文件,gradle提供了transform api,可以让我们class变为dex之前做任何想做的事情。

首先建立一个buildSrc的module,这里面创建的类都是groovy的类,所以扩展名要写groovy。至于内容嘛。。因为兼容java 随便你咯-。-

创建一个Plugin,叫做Regsiter, 只需要让他implement Plugin 插件即可, 此时重写apply方法,就可以在主工程中apply这个插件。

另外我们需要结合transform, 所以要给android插件注册一下transform

在transform里,我们就可以对所有文件进行操作了

ClassInjector 主要是使用Javassist进行对class文件的改变操作。

值得注意的是,如果操作的过程中需要使用android sdk内容,需要手动将 android.jar添加到 ClassPool里面。否则会提示找不到类的情况。

本文涉及Demo代码地址

https://github.com/githubwing/AopDemo

欢迎加入Android地方酒馆(425983695)一起研究Android技术。

参考文章

1.http://www.jianshu.com/p/dca3e2c8608a

2.http://blog.csdn.net/eclipsexys/article/details/54425414

3.http://blog.csdn.net/u010386612/article/details/51131642

[置顶] Android AOP 实践笔记的更多相关文章

  1. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  2. [置顶] Deep Learning 学习笔记

    一.文章来由 好久没写原创博客了,一直处于学习新知识的阶段.来新加坡也有一个星期,搞定签证.入学等杂事之后,今天上午与导师确定了接下来的研究任务,我平时基本也是把博客当作联机版的云笔记~~如果有写的不 ...

  3. [置顶] Linux信号相关笔记

    最近又温习了一遍Linux中的信号知识,发现有很多东西以前没有注意到,就通过这篇博客记录一下,巩固一下知识点. 一,信号基础: 信号是什么?为了回答这个问题,首先要从异常说起,这里的异常不是指c++/ ...

  4. [置顶] Android AlarmManager实现不间断轮询服务

    在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...

  5. [置顶] [Android源码分析]inquiry result引起的上层变化分析

    在上一篇文章中,我们详细分析了android是如何解析蓝牙反馈上来的搜索到的设备信息,本文将会继续分析这些信息到了上层之后是如何处理. 8.inquiry result引起的上层变化 我们知道inqu ...

  6. [置顶] Android四大组件之BroadcastReceiver

    Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...

  7. [置顶] Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  8. 【转】 [置顶] Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)

    在Android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. ...

  9. [置顶] Android 状态栏那些小坑?

    背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...

随机推荐

  1. 20145307第一周JAVA实验报告

    20145307 <Java程序设计>第一次实验实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.04.08 ...

  2. 20145313张雪纯 《Java程序设计》第7周学习总结

    20145313张雪纯 <Java程序设计>7周学习总结 教材学习内容总结 1967年定义的国际原子时,将秒的国际单位定义为铯原子辐射振动9192631170周耗费的时间. 为了简化日后对 ...

  3. 20145240《网络对抗》Web安全基础实践

    Web安全基础实践 实验后回答问题 (1)SQL注入攻击原理,如何防御 原理:SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语 ...

  4. office使用技巧

    一.excel 1.在空格内换行:ALT+ENTER 2.打出勾:插入->符号

  5. struts1.2上传多个文件

    页面:                     <input type="file" name="impFile[0]"  style="wid ...

  6. mysql索引的建立和使用

    转自[http://www.cnblogs.com/mywebname/articles/555696.html] 一.索引的概念        索引就是加快检索表中数据的方法.数据库的索引类似于书籍 ...

  7. 算数基本定理 - nefu 118

    算数基本定理 每个大于1的正整数都可以被唯一分解为素数的成绩,在乘积中的素因子按照非降序排列 a = p1^a1 * p2^a2 * ... pn^an; b = p1^b1 * p2^b2 * .. ...

  8. redis 与session

    springboot:session集中存储到redis https://www.cnblogs.com/huiy/p/6907164.html springboot处理session生命周期 htt ...

  9. docker教程目录

    为什么要用 Docker 什么是 Docker Docker 镜像 Docker容器的运用 Docker仓库 Docker如何获取镜像 CentOS 安装Docker Docker 列出镜像 Dock ...

  10. Huffuman Coding (哈夫曼编码)

    哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头 ...