Aspectj 在Android中的简单使用(Java + Kotlin)

您所在的位置:网站首页 aide支持kotlin吗 Aspectj 在Android中的简单使用(Java + Kotlin)

Aspectj 在Android中的简单使用(Java + Kotlin)

2023-11-23 17:38| 来源: 网络整理| 查看: 265

OOP&AOP

OOP(Object Oriented Programming):面向对象编程。把问题或功能模块化,每个模块处理自己的事。

AOP(Aspect Oriented Programming):面向切面编程。把分散于不同模块中的相同业务放到统一的地方来管理。如:日志记录,业务埋点,持久化,性能监控,数据校验,缓存,权限检查,异常处理等。

AspectJ简介

AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件,在编译期注入代码。代表框架:Hugo(Jake Wharton)

基本概念

Join Points:连接点,程序中可切入的点。如:方法调用时,读取某个变量时

Pointcut:切入点,代码注入的位置,其实就是有条件限定的Join Point,例如只在特定方法中注入代码

Aspect:切面,一个关注点的模块化

Advice:在切入点注入的代码,一般有before、after、around三种类型

Target Object:被一个或多个aspect横切拦截操作的目标对象

Weaving:把Advice代码织入到目标对象的过程

Inter-type declarations:用来个一个类型声明额外的方法或属性

Demo示例

给方法添加性能测试

Java版本

1.添加依赖

Project->bulid.gradle dependencies { ... classpath 'org.aspectj:aspectjtools:1.8.13' classpath 'org.aspectj:aspectjweaver:1.8.13' } Module->build.gradle dependencies { ... implementation 'org.aspectj:aspectjrt:1.8.13' } // 最后面添加即可 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.5", "-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 } } } }

2.自定义注解

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PerformanceAnnotation { String value(); }

3.自定义切面

@Aspect public class PerformanceAspect { public static final String TAG = PerformanceAspect.class.getSimpleName(); @Pointcut("execution(@ com.tongjin.aspectj.java.PerformanceAnnotation * *(..))") public void performancePointcut(){} @Around("performancePointcut()") public Object wavePerformancePointcut(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); // 类名 String className = methodSignature.getDeclaringType().getSimpleName(); // 方法名 String methodName = methodSignature.getName(); // 功能名 PerformanceAnnotation behaviorTrace = methodSignature.getMethod().getAnnotation(PerformanceAnnotation.class); String value = behaviorTrace.value(); long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); long duration = System.currentTimeMillis() - start; Log.e(TAG, String.format("%s类中%s方法执行%s功能,耗时:%dms", className, methodName, value, duration)); return result; } }

4.使用

@PerformanceAnnotation("performance") public void clickMe(View view) { Toast.makeText(this, "Click", Toast.LENGTH_SHORT).show(); }

5.日志输出

Kotlin版本

由于java版本添加依赖的方式,在kotlin中不起作用,采用大神方案

1.添加依赖

Project->build.gradle dependencies { ... classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4' } Module->bulid.gradle apply plugin: 'android-aspectjx'

2.自定义注解

@Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) annotation class PerformanceAnnotation(val value: String)

3.自定义切面

@Aspect class PerformanceAspect { companion object { val TAG = PerformanceAspect::class.java.simpleName } @Pointcut("execution(@ com.tongjin.myapplication.PerformanceAnnotation * *(..))") fun performancePointcut() { } @Around("performancePointcut()") @Throws(Throwable::class) fun wavePerformancePointcut(joinPoint: ProceedingJoinPoint) { val methodSignature = joinPoint.signature as MethodSignature // 类名 val className = methodSignature.declaringType.simpleName // 方法名 val methodName = methodSignature.name // 功能名 val behaviorTrace = methodSignature.method.getAnnotation(PerformanceAnnotation::class.java) val value = behaviorTrace.value val start = System.currentTimeMillis() joinPoint.proceed() val duration = System.currentTimeMillis() - start Log.e(TAG, "${className}类中${methodName}方法执行${value}功能,耗时:${duration}ms") } }

4.使用

@PerformanceAnnotation("performance") fun clickMe(view: View) { Toast.makeText(this, "Click", Toast.LENGTH_SHORT).show() }

5.日志输出



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3