Android AOP:最简单&粗暴(使用与原理)讲解

1.前言

  • 最近随着项目迭代业务与使用的用户逐渐增多,陆续的出现了一些性能或者BUG的问题(例如:1.某些功能执行响应慢;2.按键复电;等等)。
  • 根据上述部分性能问题,提出相对应的解决方案:
    • 某些功能执行响应慢 —> 性能监控
    • 按键复点 —> 按键防抖
  • 上述2个解决方案的最终实现原理:就是在执行函数的前或者后台添加对应的逻辑处理
  • 选择实现方式:
    1.直接在方法前后添加对应的逻辑。
    2.使用静态/动态代理。
    3.使用AOP。
  • 1与2方式:当涉及修改的方法或者类较多时,实现比较复杂,而且侵入性大,更不方便后期扩展与维护。
  • 第3方式:侵入性很少;实现简单;解耦性很大;易维护。而这种方式是如何使用?原理是什么?。
  • 今天就为大家揭开AOP的面纱。
  • 文章中实例 linhaojian的Github

2.介绍

2.1 AOP 是什么
  • AOP为Aspect Oriented Programming的缩写。意为:面向切面编程
2.2 AOP 作用
  • 通过预编译方式运行期动态代理,来改变原来执行结果的技术。
2.3 AOP 特点
  • 使原执行逻辑与改变执行逻辑解耦
  • 对原代码侵入性少
  • 容易扩展辅助功能(例如:日志)。
2.4 Android 中应用
  • 日志
  • 持久化
  • 性能监控
  • 数据校验
  • 缓存
  • 按钮防抖
  • 其他更多
2.5 AOP 术语
  • 通知、增强处理(Advice):就是你想要的功能,也就是上面说的日志、耗时计算等。
  • 连接点(JoinPoint):允许你通知(Advice)的地方,那可就真多了,基本每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点(spring只支持方法连接点)。AspectJ还可以让你在构造器或属性注入时都行,不过一般情况下不会这么做,只要记住,和方法有关的前前后后都是连接点。
  • 切入点(Pointcut):上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有十几个连接点了对吧,但是你并不想在所有方法附件都使用通知(使用叫织入,下面再说),你只是想让其中几个,在调用这几个方法之前、之后或者抛出异常时干点什么,那么就用切入点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。
  • 切面(Aspect):切面是通知和切入点的结合。现在发现了吧,没连接点什么事,连接点就是为了让你好理解切点搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过before,after,around等AOP注解就能知道),而切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。
  • 织入(weaving): 把切面应用到目标对象来创建新的代理对象的过程。
2.6 AOP 注解
  • @Aspect:声明切面,标记类
  • @Pointcut(切点表达式):定义切点,标记方法
  • @Before(切点表达式):前置通知,切点之前执行
  • @Around(切点表达式):环绕通知,切点前后执行
  • @After(切点表达式):后置通知,切点之后执行
  • @AfterReturning(切点表达式):返回通知,切点方法返回结果之后执行
  • @AfterThrowing(切点表达式):异常通知,切点抛出异常时执行

@Pointcut、@Before、@Around、@After、@AfterReturning、@AfterThrowing需要在切面类中使用,即在使用@Aspect的类中。

2.7 切点表达式

AspectJ语法1.png
AspectJ语法2.png
AspectJ语法3.png

  • 示例:
    // 返回类型:*  类名+函数名:com.lhj.test_apt..*ck(..)   
    //  com.lhj.test_apt..*ck(..)  :意思是com.lhj.test_apt包下所有类中以ck结尾的函数
    @Pointcut("execution(*  com.lhj.test_apt..*ck(..))")

3.使用

  • 3.1 项目根目录(build.gradle)的dependencies中,添加如下代码:
    dependencies {
   
        classpath 'org.aspectj:aspectjtools:1.8.13'    // add
        classpath 'org.aspectj:aspectjrt:1.8.13'       // add
    }
  • 3.2 在主项目或者需要引用的library的build.gradle中,示例如下:
apply plugin: 'com.android.library'
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
android {
   
    compileSdkVersion 28
    defaultConfig {
   
        minSdkVersion 17
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
   
        release {
   
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
   
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // aop
    implementation 'org.aspectj:aspectjrt:1.8.13'
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值