一、准备工作
- AS及Gradle版本配置,几个可用版本
As3.0.1 gradle4.4-all ndk r17
As3.2.1 gradle4.6-all
As3.4.0 gradle5.1.1-all
- 项目gradle配置
classpath 'org.aspectj:aspectjtools:1.8.9'
classpath 'org.aspectj:aspectjweaver:1.8.9'
3.module中的gradle配置(三处)
第一处
buildscript { // 编译时用Aspect专门的编译器,不再使用传统的javac
repositories {
mavenCentral()
}
dependencies {
classpath 'org.aspectj:aspectjtools:1.8.9'
classpath 'org.aspectj:aspectjweaver:1.8.9'
}
}
第二处:
//aspect的jar包
implementation 'org.aspectj:aspectjrt:1.8.13'
第三处:
//aspect支持
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
final def log = project.logger
final def variants = project.android.applicationVariants
variants.all { variant ->
if (!variant.buildType.isDebuggable()) {
log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")
return;
}
JavaCompile javaCompile = variant.javaCompile
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.8",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
log.debug "ajc args: " + Arrays.toString(args)
MessageHandler handler = new MessageHandler(true);
new Main().run(args, handler);
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break;
case IMessage.WARNING:
log.warn message.message, message.thrown
break;
case IMessage.INFO:
log.info message.message, message.thrown
break;
case IMessage.DEBUG:
log.debug message.message, message.thrown
break;
}
}
}
}
二、定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClickBehavior {
String value();
}
三、定义注解对应的Aspect类
- 在类名上加
“@Aspect”
注解,使其变成切面类 - 定义个方法1定义切入点规则,方法名随意,添加注解“
@PointCut("execution(切入点的位置)")
”注解 - 定义个方法2作为通知,方法名随意,返回值必须为
Object
,参数必须是ProceedingJoinPoint
,必须抛出异常Throwable
;并添加方法注解(切入方式)@Around("方法1方法名")
/@Before()
/@After
具体代码:
//定义此类为切面类
@Aspect
public class ClickBehaviorAspect {
private static final String TAG = "netease>>>";
//定义切入点规则
// 使用Pointcut注解,execution(切入点的位置)
@Pointcut("execution(@com.wkr.retrofit.annotation.ClickBehavior * *(..))")
public void methodPointCut() {
}
//定义织入规则:Before 方法执行前 ;After 方法执行后 ; Around 方法执行前后;参数为切入点的方法名
//方法定义规则:
// 1、方法返回值为Object
// 2、入参必须为ProceedingJoinPoint
// 3、必须抛出Throwable异常
@Around("methodPointCut()")
public Object joinPoint(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = methodSignature.getMethod();
Log.e(TAG, "<---------------方法执行前------------->");
Log.e(TAG, "方法名:" + method.getName());
Log.e(TAG, "类名:" + methodSignature.getDeclaringTypeName());
Log.e(TAG, "注解值:" + method.getAnnotation(ClickBehavior.class).value());
Object result = proceedingJoinPoint.proceed();
Log.e(TAG, "<---------------方法执行后------------->");
return result;
}
}
使用:
@ClickBehavior("登录")
public void goDl(View view) {
Log.e(TAG,"<---------------登录方法---------------->");
}
结果: