AOP面向切面编程在Android开发中的应用

本文介绍了面向切面编程(AOP)在性能调优中的应用,通过在方法上添加自定义注解,配合AOP实现对特定方法执行耗时的统计。通过预编译和运行时动态代理,可以轻松地监控如矢量化操作、渲染渐变色等关键步骤的性能,避免手动添加时间戳带来的代码冗余。同时,提供了详细的配置和切面定义示例,帮助开发者快速集成并测试AOP性能统计功能。
摘要由CSDN通过智能技术生成

面向切面编程-Aspect Oriented Programming,简称AOP,通过预编译的方式运行期间动态代理实现程序功能的统一维护的一种技术。

AOP能够做什么呢?

  • 性能检测
  • 权限验证
  • 释放资源
  • 用户行为统计

这个技术当进行性能调优的时候特别好用,配置好了只需要添加一个注解就能控制是否需要输入耗时等信息,特别容易控制,快来看看如何配置吧。

那么AOP如何使用呢?

前期准备工作

1.在主工程的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;
            }
        }
    }
}

2.然后在libs 下面添加 aspectjrt.jar

下面进入是具体实现

  • 定义一个注解,用来标识哪些是需要统计的。
  • 将相应的注解添加到需要统计的方法上
  • 定义切面规则
    • 在原来应用中的哪些注释的地方放到切面进行处理
    • 对进入切面的内容如何处理

现在有这样一个需求,客户要求统计轮廓线各个特效的耗时情况

  • 获取轮廓线耗时
  • 单独矢量化的耗时
  • 矢量化后增加单色渲染耗时
  • 矢量化后增加渐变色颜色耗时
  • 矢量化+粉笔+单色耗时
  • 矢量化+粉笔+渐变色耗时
  • 线条矢量化+荧光笔+单色耗时
  • 线条矢量化+荧光笔+渐变色耗时
  • 线条矢量化+单色渲染+网点耗时
  • 线条矢量化+单色渲染+排线耗时

如果不采用AOP,就需要在方法前后添加时间戳,copy很多重复的代码才可以,下面通过AOP来处理。

3.定义一个注解类

@Target(ElementType.METHOD)  //使用在方法上
@Retention(RetentionPolicy.RUNTIME) //到运行期间都要存在
public @interface BehaviorTrace {

    String value();

}

用来标识哪些地方需要统计性能标识

4.标识需要统计性能的方法

/**
 * 对图片进行矢量化
 */
@BehaviorTrace("矢量化操作")
public void vectorBitmap() {
    if (mLineBitmap == null) {
        Log.e("meicam", "mLineBitmap is null");
        return;
    }
    String lineJsonStr = mImageEffectContext.getVectorDataFromImage(mLineBitmap, -0.6f);
    mVectBitmap = mImageEffectContext.renderVectorEffect(mLineBitmap, lineJsonStr, mSrcImageWidth, mSrcImageHeight);
    ivImage.setImageBitmap(mLineBitmap);
}

   /**
     * 渐变色
     */
    @BehaviorTrace("渲染渐变色")
    private void gradientColor() {
        if (mVectBitmap == null) {
            Log.e("meicam", "mLineBitmap is null");
            return;
        }
        Bitmap bmp = mImageEffectContext.renderColorEffect(mVectBitmap, Color.RED,
                Color.WHITE,
                Color.GREEN, mSrcImageWidth, mSrcImageHeight, true, false);
        ivImage.setImageBitmap(bmp);
    }

像上面这个方式标记需要统计的方法

3.写切面类

@Aspect
public class BehaviorAspect {

    //切面规则
    //1.在原来的应用中哪些注释的地方放到切面上 
    @Pointcut("execution(@com.meishe.imageshow.annotation.BehaviorTrace * *(..))")
    public void fromBehaviorTrace(){}

    //2.对进行切面的进行处理
    //@Before  触发之前调用
    //@After	触发之后调用
    //@Around   触发期间调用
    @Around("fromBehaviorTrace()")
    public Object joinPoint(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //方法签名
        String methodName = signature.getName(); //方法名
        String className = signature.getDeclaringType().getName();
        String value = signature.getMethod().getAnnotation(BehaviorTrace.class).value();
        //统计时间
        long beginTime=System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long duration=System.currentTimeMillis()-beginTime;
        Log.d("lpf",String.format("%s-->%s-->%s-->耗时%d ms",className,methodName,value,duration));
        return proceed;
    }

}

上面是实际项目中的两个方法,我分析耗时的一个配置方式。
这样就可以输出对图片进行矢量化方法的耗时以及渐变色的耗时了,这里的数据也可以写入到本地文件,推送到服务器等。如果想测试其他方法的耗时直接在方法中添加 @BehaviorTrace 这个注解就可以了,赶紧配置来试试吧……

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值