注意代码为Kotlin

什么是OOP、什么是AOP?

OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分,而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

AOP的应用场景

AOP编程的主要用途有:日志记录,行为统计,安全控制,事务处理,异常处理,系统统一的认证、权限管理等。

AspectJ是什么?

AspectJ是一个面向切面编程的一个框架,它扩展了java语言,并定义了实现AOP的语法。在将.java文件编译为.class文件时默认使用javac编译工具,AspectJ会有一套符合java字节码编码规范的编译工具来替代javac,在将.java文件编译为.class文件时,会动态的插入一些代码来做到对某一类特定东西的统一处理。通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的技术。对业务逻辑的各个部分进行隔离,耦合度降低,提高程序的可重用性,同时提高了开发的效率。

管网: https://www.eclipse.org/aspectj/

Kotlin版:https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx

通过Aspect实现防止多点击

1.引入Aspectj

  • 在项目根目录下的build.gradle中,添加依赖
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'
  • 在app或其他module目录下的build.gradle中,添加以下代码:
plugins {id 'com.android.library'id 'kotlin-android'id 'android-aspectjx'//Aspectj添加
}

2.添加一个自定义注解

/*** AnnotationRetention.SOURCE:不存储在编译后的 Class 文件。* AnnotationRetention.BINARY:存储在编译后的 Class 文件,但是反射不可见。* AnnotationRetention.RUNTIME:存储在编译后的 Class 文件,反射可见。*/
@Retention(AnnotationRetention.RUNTIME)
/*** AnnotationTarget.CLASS:类,接口或对象,注解类也包括在内。* AnnotationTarget.ANNOTATION_CLASS:只有注解类。* AnnotationTarget.TYPE_PARAMETER:Generic type parameter (unsupported yet)通用类型参数(还不支持)。* AnnotationTarget.PROPERTY:属性。* AnnotationTarget.FIELD:字段,包括属性的支持字段。* AnnotationTarget.LOCAL_VARIABLE:局部变量。* AnnotationTarget.VALUE_PARAMETER:函数或构造函数的值参数。* AnnotationTarget.CONSTRUCTOR:仅构造函数(主函数或者第二函数)。* AnnotationTarget.FUNCTION:方法(不包括构造函数)。* AnnotationTarget.PROPERTY_GETTER:只有属性的 getter。* AnnotationTarget.PROPERTY_SETTER:只有属性的 setter。* AnnotationTarget.TYPE:类型使用。* AnnotationTarget.EXPRESSION:任何表达式。* AnnotationTarget.FILE:文件。* AnnotationTarget.TYPEALIAS:@SinceKotlin("1.1") 类型别名,Kotlin1.1已可用。*/
@Target(AnnotationTarget.FUNCTION)
annotation class AopOnclick(val outTime:Long = 500)

3.添加重复点击判断逻辑

import android.os.SystemClockobject AopClickUtil {/*** 最近一次点击的时间*/private var mLastClickTime: Long = 0/*** 是否是快速点击** @param intervalMillis  时间间期(毫秒)* @return  true:是,false:不是*/fun isFastDoubleClick(intervalMillis: Long): Boolean {//        long time = System.currentTimeMillis();val time = SystemClock.elapsedRealtime()val timeInterval = Math.abs(time - mLastClickTime)return if (timeInterval < intervalMillis) {true} else {mLastClickTime = timefalse}}
}

4.AOP处理类

package com.wpf.apiimport org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Pointcut
import org.aspectj.lang.reflect.MethodSignature/**
@Pointcut("execution(" +//执行语句
"@com.wpf.api.AopOnclick" +//注解筛选
"*" + //类路径,*为任意路径
"*" + //方法名,*为任意方法名
"(..)" +//方法参数,'..'为任意个任意类型参数
")" +
" && " +//并集
)
@Aspect:声明切面,标记类
@Pointcut(切点表达式):定义切点,标记方法
@Before(切点表达式):前置通知,切点之前执行
@Around(切点表达式):环绕通知,切点前后执行
@After(切点表达式):后置通知,切点之后执行
@AfterReturning(切点表达式):返回通知,切点方法返回结果之后执行
@AfterThrowing(切点表达式):异常通知,切点抛出异常时执行* */
@Aspect
class AopClickAspect {/*** 定义切点,标记切点为所有被@AopOnclick注解的方法* 注意:这里com.wpf.api.AopOnclick需要替换成* 你自己项目中AopOnclick这个类的全路径*/@Pointcut("execution(@com.wpf.api.AopOnclick * *(..))")fun methodAnnotated(){}/*** 定义一个切面方法,包裹切点方法*/@Around("methodAnnotated()")@Throws(Throwable::class)fun aroundJoinPoint(joinPoint: ProceedingJoinPoint) {// 取出方法的注解val methodSignature = joinPoint.signature as MethodSignatureval method = methodSignature.methodif (!method.isAnnotationPresent(AopOnclick::class.java)) {return}val aopOnclick = method.getAnnotation(AopOnclick::class.java)// 判断是否快速点击if (!AopClickUtil.isFastDoubleClick(aopOnclick.outTime)) {// 不是快速点击,执行原方法joinPoint.proceed()}}
}

5.方法调用

    @AopOnclickoverride fun onClick(v: View) {if (v.id == R.id.hello_World){Log.e("wpf","点击hello")}}

采坑记录

问题1:java.util.zip.ZipException: zip file is empty

解决方式:

android {aspectjx {//排除所有package路径中包含`android.support`的class文件及库(jar文件)exclude 'android.support'exclude 'versions.9'}
}

问题2:Cannot cast object ‘com.android.build.gradle.internal.pipeline.TransformTask

解决方式:
根build.gradle文件中配置的gradle版本和aspectjx匹配,如我的配置。

buildscript {ext.kotlin_version = "1.4.32"repositories {google()jcenter()}dependencies {classpath "com.android.tools.build:gradle:4.1.3"classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//AspectJXclasspath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'}
}

代码链接

https://download.csdn.net/download/fepengwang/20398670

android 实现AOP 使用Aspectj Kotlin版相关推荐

  1. Android 开源网络框架OKHttp4 Kotlin版本源码解析

    Android 开源网络框架OKHttp 4 解析 文章目录 Android 开源网络框架OKHttp 4 解析 1.Http2.0协议主要增加的优化点: 2.OkHttp支持的内容 3.OkHttp ...

  2. 【AOP 面向切面编程】Android Studio 中配置 AspectJ ( 下载并配置AS中 jar 包 | 配置 Gradle 和 Gradle 插件版本 | 配置 Gradle 构建脚本 )

    文章目录 一.AspectJ 下载 二.拷贝 aspectjrt.jar 到 Android Studio 三.配置 Gradle 和 Gradle 插件版本 四.配置 Gradle 构建脚本 一.A ...

  3. Android 蓝牙开发(扫描设备、绑定、解绑)Kotlin版

    Kotlin版 蓝牙开发 (扫描设备.绑定.解绑) 前言 运行效果图 正文 ① 配置项目 ② 布局和样式 ③ 编码 1. 通知栏样式修改 2. 蓝牙设备列表适配器编写 3. 权限请求 4. 初始化蓝牙 ...

  4. kotlin版仿哔哩哔哩动画Android客户端(哔哩哔哩 (゜-゜)つロ 干杯~-bilibili)

    前言 kotlin 版由于几年前对于kotlin还不熟悉,许多地方不规范 该仿的项目为原项目的kotlin版,由于本人水平有限,有些kotlin写法不规范,后期会逐步完善,和原开源项目一样采用mvp+ ...

  5. Android WebView支持文件下载之调起浏览器下载(Java与Kotlin版)

    使用函数 WebView默认没有开启文件下载的功能,如果想使得WebView能够支持文件下载,就需要给WebView设置下载监听器setDownloadListener,每当有文件需要下载时,就会回调 ...

  6. 深入理解Android之AOP

    格式更加精美的PDF版请到:http://vdisk.weibo.com/s/z68f8l0xTgCLK 下载 一.闲谈AOP 大家都知道OOP,即ObjectOriented Programming ...

  7. 在Android项目中使用AspectJ

    版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/8888459.html 什么是AOP AOP是 Aspec ...

  8. AOP之AspectJ简单使用

    为什么80%的码农都做不了架构师?>>>    参考文章: 使用AspectJ在Android中实现Aop 深入理解Android之AOP 自动打印日志 主要知识点: 主要是JPoi ...

  9. AspectJ注解版和XML版

    什么是AspectJ? AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. Aspec ...

最新文章

  1. 怎么用python找论文_如何利用Python绘制学术论文图表方法
  2. php memcache 封装类,PHP 自定义session储存 MEMCACHE 方式类
  3. 机器学习模型越来越大,开发者应该如何部署?
  4. .net中使用反射的简单例子
  5. hashmap允许null键和值吗_hashMap底层源码浅析
  6. 深入理解C/C++二维数组
  7. linux下mysql数据库目录迁移_linux下mysql数据库目录迁移问题
  8. centos6.4修改网卡名
  9. EE Servlet 3:在Servlet中生成HTML输出
  10. 1.2 如何在visual studio 中建立C#程序
  11. 64位和32位的区别
  12. 模板题——中国剩余定理,求组合数,卡特兰数
  13. ListView刷新某一项Item
  14. vue路由变化时使用axios取消所有请求
  15. 在开源中国众包那里放了一个东西
  16. 5G NR MCG,SCG,PCell,PSCell,SCell,sPCell 概念
  17. flutter 项目实践2
  18. WAF是什么?一篇文章带你全面了解WAF
  19. Linux:生成core的几种方式
  20. 如何高效的进行空值的填充

热门文章

  1. Windows中Nginx下载、安装、配置
  2. 【Windows必备软件】01 Groupy 实现你所有的窗口标签化管理
  3. C# Serializable标签 和序列化
  4. io复用相对于多进程、多线程的优势
  5. 前端面试查漏补缺--(二) 垃圾回收机制
  6. RGB图像卷积生成Feature map特征图过程
  7. USB-DFP UFP DRP模式
  8. 直方图处理(规定化)
  9. 牛客网Veirlog刷题答案目录(持续更新)
  10. ostu阈值分割python实现_Otsu阈值OpenCV Python