AOP在Android开发中的使用
2020-04-20 本文已影响0人
Wocus
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
Aop思想可以说成插桩,在类的编译期间中干一些东西,下图看一个图就明白了,主要关注一下AspectJ插入时机
image.png
接下来开始在Android开发中引入AOP
由于现在Kotlin已经成Android开发的趋势,AOP的适配也需要兼容Kotlin,所以这里引用github开源项目实现
github开源项目:https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx
1.引入插件
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
dependencies {
//我这里使用的是3.6.2
classpath 'com.android.tools.build:gradle:3.6.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
//最新版本为2.1.0
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'
}
}
2.应用插件
apply plugin: 'android-aspectjx'
3.配置排除第三方包名冲突,这一步不配置,编译的时候会报错:java.util.zip.ZipException: zip file is empty
aspectjx{
exclude 'androidx','com.google','com.squareup','com.alipay','org.apache'
}
4.开始编写一个防止双击的AOP
定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SingleClick {
/**
* 快速点击的间隔
*/
long value() default 1000;
}
实现注解,在方法切入点修改成自己使用的切入规则
@Aspect
public class SingleClickAspect {
/**
* 最近一次点击的时间
*/
private long mLastTime;
/**
* 最近一次点击的控件ID
*/
private int mLastId;
/**
* 方法切入点
*/
@Pointcut("execution(@com.sunnet.shipcargo.aop.SingleClick * *(..))")
public void method() {}
/**
* 在连接点进行方法替换
*/
@Around("method() && @annotation(singleClick)")
public void aroundJoinPoint(ProceedingJoinPoint joinPoint, SingleClick singleClick) throws Throwable {
View view = null;
for (Object arg : joinPoint.getArgs()) {
if (arg instanceof View) {
view = (View) arg;
}
}
if (view != null) {
long currentTime = Calendar.getInstance().getTimeInMillis();
if (currentTime - mLastTime < singleClick.value() && view.getId()
== mLastId) {
Log.i("SingleClick", "发生快速点击");
return;
}
mLastTime = currentTime;
mLastId = view.getId();
//执行原方法
joinPoint.proceed();
}
}
}
5.使用
/**
* 发送验证码
*/
@SingleClick
private fun sendCode(view: View){
Log.d("验证码", "验证码")
}
运行结果
image.png