沪江 AOP 切片 API使用说明

官方参考

https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx

AOP 切片编程 SDK使用

  • build.gradle
buildscript {
    repositories {
        mavenLocal()
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        // 沪江网AOP插件,使用比较简单
        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.8'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}
  • app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'android-aspectjx'

android {
    compileSdkVersion 29
    buildToolsVersion '26.0.2'
    defaultConfig {
      // 省略...
    }

    buildTypes {
      // 省略...
    }

    // 省略...

    aspectjx {
        enabled true //关闭AspectJX功能。开关控制
    }
}
  • app/proguard-rules.pro
# 保持泛型不被混淆
-keepattributes Signature

# 保留所有注解,避免混淆时,注解丢失
-keepattributes *Annotation*
-keep class * extends java.lang.annotation.Annotation { *; }

# 不混淆使用了注解的类及类成员
-keep @com.aop.test.Timer class * {*;}
# 如果类中有使用了注解的方法,则不混淆类和类成员
-keepclasseswithmembers class * {
    @com.aop.test.Timer <methods>;
}
# 如果类中有使用了注解的字段,则不混淆类和类成员
-keepclasseswithmembers class * {
    @com.aop.test.Timer <fields>;
}
# 如果类中有使用了注解的构造函数,则不混淆类和类成员
-keepclasseswithmembers class * {
    @com.aop.test.Timer <init>(...);
}

# AspectJ注解引用的对象必须被keep。比如注解的函数的入参类
-keep class com.aop.test.Device
  • com/aop/test/Timer.java 注解类
package com.aop.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 定义注解
 *
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
    String value() default "";
}
  • com/aop/test/ConnectionAspect.java 切片类
package com.aop.test;

import android.text.TextUtils;
import android.util.Log;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 当注解的函数的参数中包含自定义对象时,该对象不能被混淆,否则{@link MethodSignature#getMethod()}方法无法获取函数对象。
 *
 * @since 2021-02-24
 */
@Aspect
public class ConnectionAspect {
    private static final String TAG = "ConnectionAspect";

    @Pointcut("execution(@com.aop.test.Timer * *(..))")
    public void method() {
    }

    @Before("method()")
    public void record(JoinPoint joinPoint) throws Throwable {
        if (Objects.isNull(joinPoint) || Objects.isNull(joinPoint.getSignature()) || !(joinPoint.getSignature() instanceof MethodSignature)) {
            return;
        }
        long startTime = System.currentTimeMillis();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Log.v(TAG, "joinPoint signature name " + signature.getName() + ", class " + signature.getDeclaringTypeName());
        Method method = signature.getMethod();
        if (Objects.isNull(method)) {
            Log.e(TAG, signature.getName() + " method is null");
            return;
        }
        Timer timer = method.getAnnotation(Timer.class);
        if (Objects.isNull(timer)) {
            Log.e(TAG, signature.getName() + " timer is null");
            return;
        }
        map.put(timer.value(), startTime);
    }
}

AOP报错ProceedingJoinPoint is only supported for around advice

  • 这是因为在返回后通知(@AfterReturning)和抛出异常后通知(@AfterThrowing)的方法中不能使用ProceedingJoinPoint,使用JoinPoint即可解决.
  • @Before 和 @After入参是JoinPoint,不是 ProceedingJoinPoint
  • 报错如下
> Task :app:transformClassesWithDesugarForRelease
:app:transformClassesWithDesugarForRelease spend 2245ms
use of ProceedingJoinPoint is allowed only on around advice (arg 0 in (before(extraFlags: 2): (execution(@com.huawei.sinktester.chenggong.Timer * *(..)) && persingleton(com.huawei.sinktester.chenggong.TimerRecord))->void com.huawei.sinktester.chenggong.TimerRecord.record(org.aspectj.lang.ProceedingJoinPoint)))

use of ProceedingJoinPoint is allowed only on around advice (arg 0 in (before(extraFlags: 2): (execution(@com.huawei.sinktester.chenggong.Timer * *(..)) && persingleton(com.huawei.sinktester.chenggong.TimerRecord))->void com.huawei.sinktester.chenggong.TimerRecord.record(org.aspectj.lang.ProceedingJoinPoint)))

混淆时,需要配置

  • 不混淆使用了注解的类及类成员
    -keep @com.pang.view.base.annotation.ViewInject class * {*;}
  • 如果类中有使用了注解的方法,则不混淆类和类成员
    -keepclasseswithmembers class * {
    @com.pang.view.base.annotation.ViewInject ;
    }
  • 如果类中有使用了注解的字段,则不混淆类和类成员
    -keepclasseswithmembers class * {
    @com.pang.view.base.annotation.ViewInject ;
    }
  • 如果类中有使用了注解的构造函数,则不混淆类和类成员
    -keepclasseswithmembers class * {
    @com.pang.view.base.annotation.ViewInject (…);
    }
  • The “Signature” attribute is required to be able to access generic types whencompiling in JDK 5.0 and higher.
    -keepattributes Signature
  • processing Annotations
    -keepattributes Annotation
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值