本文同步自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. 20145329 《Java程序设计》实验一总结

    实验指导教师:娄嘉鹏老师 实验日期:2016.4.8 实验时间:16:30~18:30 实验序号:实验一 实验名称:Java开发环境的熟悉 实验目的与要求: 使用JDK编译.运行简单的Java程序. ...

  2. java处理json的工具类(list,map和json的之间的转换)

    需要下载第三方的jar :net.sf.json import java.io.BufferedReader; import java.io.InputStream; import java.io.I ...

  3. Servlet3.0异步请求

    在Servlet3.0之前,Servlet采用Thread-Per-Request的方式处理请求 即每次Http请求都有一个线程从头到尾负责处理 如果一个请求需要进行IO操作,比如访问数据库.调用第三 ...

  4. HA-web-services

    一.HA部署 本次实验的程序选型为heartbeat v1 + hearesources.资源有IP和httpd,filesystem 配置HA集群的前提: (1)各节点资源一致,硬件或软件环境一致 ...

  5. Import SQL into MySQL with a progress meter

    There is nice tool called pv # On Ubuntu/Debian system $ sudo apt-get install pv # On Redhat/CentOS ...

  6. 爬虫之JSON案例

    糗事百科实例: 爬取糗事百科段子,假设页面的URL是 http://www.qiushibaike.com/8hr/page/1 要求: 使用requests获取页面信息,用XPath / re 做数 ...

  7. LeetCode——Increasing Triplet Subsequence

    Question Given an unsorted array return whether an increasing subsequence of length 3 exists or not ...

  8. Spring的配置相关知识(学习spring boot的预备知识)

    我们经常说的控制反转(Inversion of Control-IOC)和依赖注入(dependency injection-DI)在Spring环境下是等同的概念,控制反转是通过依赖注入实现的.所谓 ...

  9. 关于推荐库位 java前端与SQL语句后面的结合

    ----------------------------------------------------------------------------------- select a1.id,a1. ...

  10. SVM(三)线性支持向量机

    本文是在微信公众号发表的原创~ 额,图片粘不过来~就把链接给你们吧 http://mp.weixin.qq.com/s?__biz=MjM5MzM5NDAzMg==&mid=400740076 ...