cotlin java go_Aspectj 在Android中的简单使用(Java + Kotlin)-Go语言中文社区

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.日志输出

c95bb60e7c2df5cd30c70d3a78a309eb.png

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.日志输出

d93c1500f51f92502794d1f0bbb747c8.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值