Android AspectJ común Buried, interceptar, supervisar el uso de anotaciones

Hacer un registro de aprendizaje:

Android AOP programación en
AOP del androide
androide de encargo del estudio complemento Gradle
ver en Android AspectJ fuerte inserción
jarryleo / MagicBuriedPoint

Los dos usos AspectJ

(1) modificado con un puntos de entrada de anotación de encargo, los puntos de entrada controlados con precisión, es de tipo invasivo;

(2) no requiere ninguna modificación en el código en el punto de entrada, es no invasivo.

intruso

el uso invasivo, típicamente usando un anotaciones personalizados, como una regla de selección de punto de entrada.

No invasiva

No invasiva, que no requiere el uso de notas adicionales para modificar el punto de entrada, punto de entrada sin modificar el código.

proyectos de acceso utilizan:

En general, vamos a crear un módulo separado proporciona acceso a otros proyectos para utilizar el módulo de abajo TrackPoint

configuración del módulo build.gradle

Dos maneras: 1. aplicar plugins: 'android-aspectjx'

                  2.La aplicación 'org.aspectj: aspectjrt: 1.8 +.'

Notas maneras:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AspectAnalyze {
    String name();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AspectDebugLog {
}
public class MainActivity extends Activity {
    private Button myButton;
    private final String TAG= this.getClass().getSimpleName();

    @AspectAnalyze(name = "MainActivity.onCreate")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myButton=findViewById(R.id.myButton);
        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this,"text",Toast.LENGTH_LONG).show();
                onNameClick();
            }
        });
    }

    @AspectDebugLog
    @AspectAnalyze(name = "onNameClick")
    public void onNameClick() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @AspectAnalyze(name = "MainActivity.onDestroy")
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }
}
package com.trackpoint;

import android.util.Log;

import com.trackpoint.annotation.AspectAnalyze;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.reflect.SourceLocation;

@Aspect
public class AnnotationAspectTrace {
    private final String TAG = this.getClass().getSimpleName();
    private static AspectTraceListener aspectTraceListener;

    /**
     * 针对所有继承 Activity 类的 onCreate 方法
     */
    @Pointcut("execution(* android.app.Activity+.onCreate(..))")
    public void activityOnCreatePointcut() {

    }

    /**
     * 针对带有AspectAnalyze注解的方法
     */
    @Pointcut("execution(@com.trackpoint.annotation.AspectAnalyze * *(..))")
    public void aspectAnalyzeAnnotation() {
    }
    /**
     * 针对带有AspectAnalyze注解的方法
     */
    @Pointcut("execution(@com.trackpoint.annotation.AspectDebugLog * *(..))")
    public void aspectDebugLogAnnotation() {
    }
    /**
     * 针对前面 aspectAnalyzeAnnotation() 的配置
     */
    @Around("aspectAnalyzeAnnotation()")
    public void aroundJoinAspectAnalyze(final ProceedingJoinPoint joinPoint) throws Throwable {
        Object target = joinPoint.getTarget();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        AspectAnalyze aspectAnalyze = methodSignature.getMethod().getAnnotation(AspectAnalyze.class);
        long startTimeMillis = System.currentTimeMillis();
        joinPoint.proceed();
        if (aspectTraceListener != null) {
            aspectTraceListener.onAspectAnalyze(joinPoint, aspectAnalyze, methodSignature, System.currentTimeMillis() - startTimeMillis);
        }
    }
    /**
     * 针对前面 aspectDebugLogAnnotation() 或 activityOnCreatePointcut() 的配置
     */
    @Around("aspectDebugLogAnnotation() || activityOnCreatePointcut()")
    public void aroundJoinAspectDebugLog(final ProceedingJoinPoint joinPoint) throws Throwable {
        long startTimeMillis = System.currentTimeMillis();
        joinPoint.proceed();
        long duration = System.currentTimeMillis() - startTimeMillis;
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        SourceLocation location = joinPoint.getSourceLocation();
        String message = String.format("%s(%s:%s) [%sms]", methodSignature.getMethod().getName(), location.getFileName(), location.getLine(), duration);
        if (aspectTraceListener != null) {
            aspectTraceListener.logger("AspectTrace", message);
        } else {
            Log.e("AspectTrace", message);
        }
    }

    public static void setAspectTraceListener(AspectTraceListener aspectTraceListener) {
        AnnotationAspectTrace.aspectTraceListener = aspectTraceListener;
    }

    public interface AspectTraceListener {
        void logger(String tag, String message);

        void onAspectAnalyze(ProceedingJoinPoint joinPoint, AspectAnalyze aspectAnalyze, MethodSignature methodSignature, long duration);
    }
}

No invasiva:

Los siguientes son varios escenarios comunes

package com.trackpoint;

import android.util.Log;
import android.widget.Toast;

import com.trackpoint.annotation.AspectAnalyze;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
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 org.aspectj.lang.reflect.SourceLocation;

@SuppressWarnings("unused")
@Aspect
public class AspectTrace {
    private final String TAG = "AspectTrace";

    @Around("call(* android.widget.Toast.setText(java.lang.CharSequence))")
    public void handleToastText(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Log.d(TAG," start handleToastText");
        proceedingJoinPoint.proceed(new Object[]{"处理过的toast"}); //这里把它的参数换了
        Log.d(TAG," end handleToastText");
    }

    @Before("call(* android.widget.Toast.show())")
    public void changeToast(JoinPoint joinPoint) throws Throwable {
        Toast toast = (Toast) joinPoint.getTarget();
        toast.setText("修改后的toast");
        Log.d(TAG, " --> changeToast");
    }

    /**
     * 在MainActivity的所有生命周期的方法中打印log
     * @param joinPoint
     * @throws Throwable
     */
    @Before("execution(* android.app.Activity.**(..))")
    public void method(JoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String className = joinPoint.getThis().getClass().getSimpleName();
        Log.e(TAG, "class:" + className+" method:" + methodSignature.getName());
    }

}

@Aspect
public class ViewAspect {
    private final String TAG = "ViewAspect";

    @Pointcut("execution(void android.view.View.OnClickListener.onClick(..))")
    public void onClickPointcut() {
    }

    @Pointcut("execution(* *.*onTouch(..))")
    public void onTouchPointcut() {
        Log.d(TAG,"onTouchPointcut");
    }


    @Around("onClickPointcut()")
    public void aroundJoinClickPoint(final ProceedingJoinPoint joinPoint) throws Throwable {
        Object target = joinPoint.getTarget();
        String className = "";
        if (target != null) {
            className = target.getClass().getName();
        }
        //获取点击事件view对象及名称,可以对不同按钮的点击事件进行统计
        Object[] args = joinPoint.getArgs();
        if (args.length >= 1 && args[0] instanceof View) {
            View view = (View) args[0];
            int id = view.getId();
            String entryName = view.getResources().getResourceEntryName(id);
            TrackPoint.onClick(className, entryName);
        }
        joinPoint.proceed();//执行原来的代码
    }
}

encuentran problemas:

1. El uso del proceso a menudo no hace interfaz OnTouch (..)

2. Cada cambio de aspecto necesidades de código a los artículos limpios

github demostración Código: https://github.com/xingchongzhu/AspectJDemo

Publicado 92 artículos originales · ganado elogios 27 · Vistas a 90000 +

Supongo que te gusta

Origin blog.csdn.net/zhuxingchong/article/details/104756795
Recomendado
Clasificación