aop是一套所有架构师(不限语言)都必需掌握的技术,主要应用于全局业务,如性能监测、权限验证、释放资源、用户行为统计等。
使用工具:Android中可以使用aspectj工具。
原理:可以用于在android 打包,class转换成dex 过程中,加入开发者自定义的处理逻辑.
核心技术:动态代理,遵循java编译原则,编译修改后的class文件。
具体使用步骤:
1.在将aspectjrt.jar包添加到libs目录并引入。
2.在app的build.gradle中加入如下配置
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath'org.aspectj:aspectjtools:1.8.8'
classpath'org.aspectj:aspectjweaver:1.8.8'
}
}
....
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;
}
}
}
}
3.创建注解,如性能检测注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BehaviorTrace {
String value();
}
4.在需要检测的方法上添加改注解
@BehaviorTrace("摇一摇")
public void shakeClick(View view) {
SystemClock.sleep(new Random().nextInt(2000));
}
5.创建一个切面类,添加@Aspect注解
@Aspect
public class BehaviorTraceAspect {
//定义切面的规则
//1.就在原来应用中哪些注释的地方放到当前切面进行处理
//execution(注释名 注释用的地方)
//@后面为自定义注解的全类名
// * *(..) 表示任何类 任何方法(任何参数)
@Pointcut("execution(@com.example.testdemo.annotation.BehaviorTrace * *(..))")
public void methodAnnotatedWithBehaviorTrace(){}
//2.对进入切面的内容如何处理
//advice
//@Before() 在切入点之前运行
//@After() 在切入点之后运行
//@Around() 在切入点前后都运行
@Around("methodAnnotatedWithBehaviorTrace()")
public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable{
MethodSignature methodSignature=(MethodSignature)joinPoint.getSignature();
String className=methodSignature.getDeclaringType().getSimpleName();
String methodName=methodSignature.getName();
String funName=methodSignature.getMethod().getAnnotation(BehaviorTrace.class).value();
//统计时间
long begin=System.currentTimeMillis();
Object result=joinPoint.proceed();
long duration=System.currentTimeMillis()-begin;
Log.d("yxg",String.format("功能:%s,%s类的%s方法执行了,用时%d ms",funName,className,methodName,duration));
return result;
}
}
网友评论