Instrucciones de la API de corte de Hujiang AOP

referencia oficial

https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx

Uso del SDK de programación de sectores AOP

  • construir.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()
    }
}
  • aplicación/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'android-aspectjx'

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

    buildTypes {
      // 省略...
    }

    // 省略...

    aspectjx {
        enabled true //关闭AspectJX功能。开关控制
    }
}
  • aplicación/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 clase de anotación
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 clase de segmento
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 solo se admite para consejos aproximados

  • Esto se debe a que ProceedingJoinPoint no se puede utilizar en los métodos de notificación posterior a la devolución (@AfterReturning) y notificación de excepción posterior al lanzamiento (@AfterThrowing), y se puede resolver mediante JoinPoint.
  • Los parámetros de entrada @Before y @After son JoinPoint, no ProceedingJoinPoint
  • El error se informa de la siguiente manera.
> 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)))

Al ofuscar, se requiere configuración

  • No confunda clases anotadas y miembros de clase:
    mantenga @com.pang.view.base.annotation.ViewInject class * {*;}
  • Si hay métodos anotados en la clase, la clase y los miembros de la clase no se confundirán
    -keepclasseswithmembers class * { @com.pang.view.base.annotation.ViewInject; }

  • Si hay campos anotados en la clase, no confunda la clase y los miembros de la clase
    -keepclasseswithmembers class * { @com.pang.view.base.annotation.ViewInject; }

  • Si hay un constructor anotado en la clase, la clase y los miembros de la clase no se confundirán
    -keepclasseswithmembers class * { @com.pang.view.base.annotation.ViewInject (…); }

  • El atributo "Firma" es necesario para poder acceder a tipos genéricos al compilar en JDK 5.0 y superior.
    -keepattributes Firma
  • Procesando anotaciones
    - Keepattributes Anotación

Supongo que te gusta

Origin blog.csdn.net/followYouself/article/details/119356346
Recomendado
Clasificación