当前位置:   article > 正文

Android AspectJ 常用埋点,拦截,监听注解使用_string aspect监听annotation

string aspect监听annotation

做一个学习记录:

Android中的AOP编程
Android之AOP
Android Studio 中自定义 Gradle 插件
看AspectJ在Android中的强势插入
jarryleo / MagicBuriedPoint

AspectJ 的两种用法

(1)用自定义注解修饰切入点,精确控制切入点,属于侵入式;

(2)不需要在切入点代码中做任何修改,属于非侵入式。

侵入式

侵入式用法,一般会使用自定义注解,以此作为选择切入点的规则。

非侵入式

非侵入式,就是不需要使用额外的注解来修饰切入点,不用修改切入点的代码。

项目接入使用:

一般情况下我们会新建一个独立模块提供给其它项目接入使用,如下图TrackPoint模块

build.gradle模块配置

两种方式:1.apply plugin: 'android-aspectjx'

                  2.implementation 'org.aspectj:aspectjrt:1.8.+'

注解方式:

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.METHOD)
  3. public @interface AspectAnalyze {
  4. String name();
  5. }
  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.METHOD)
  3. public @interface AspectDebugLog {
  4. }
  1. public class MainActivity extends Activity {
  2. private Button myButton;
  3. private final String TAG= this.getClass().getSimpleName();
  4. @AspectAnalyze(name = "MainActivity.onCreate")
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. myButton=findViewById(R.id.myButton);
  10. myButton.setOnClickListener(new View.OnClickListener() {
  11. @Override
  12. public void onClick(View view) {
  13. Toast.makeText(MainActivity.this,"text",Toast.LENGTH_LONG).show();
  14. onNameClick();
  15. }
  16. });
  17. }
  18. @AspectDebugLog
  19. @AspectAnalyze(name = "onNameClick")
  20. public void onNameClick() {
  21. try {
  22. Thread.sleep(500);
  23. } catch (InterruptedException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. @AspectAnalyze(name = "MainActivity.onDestroy")
  28. @Override
  29. protected void onDestroy() {
  30. super.onDestroy();
  31. }
  32. @Override
  33. protected void onResume() {
  34. super.onResume();
  35. }
  36. }
  1. package com.trackpoint;
  2. import android.util.Log;
  3. import com.trackpoint.annotation.AspectAnalyze;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.Around;
  6. import org.aspectj.lang.annotation.Aspect;
  7. import org.aspectj.lang.annotation.Pointcut;
  8. import org.aspectj.lang.reflect.MethodSignature;
  9. import org.aspectj.lang.reflect.SourceLocation;
  10. @Aspect
  11. public class AnnotationAspectTrace {
  12. private final String TAG = this.getClass().getSimpleName();
  13. private static AspectTraceListener aspectTraceListener;
  14. /**
  15. * 针对所有继承 Activity 类的 onCreate 方法
  16. */
  17. @Pointcut("execution(* android.app.Activity+.onCreate(..))")
  18. public void activityOnCreatePointcut() {
  19. }
  20. /**
  21. * 针对带有AspectAnalyze注解的方法
  22. */
  23. @Pointcut("execution(@com.trackpoint.annotation.AspectAnalyze * *(..))")
  24. public void aspectAnalyzeAnnotation() {
  25. }
  26. /**
  27. * 针对带有AspectAnalyze注解的方法
  28. */
  29. @Pointcut("execution(@com.trackpoint.annotation.AspectDebugLog * *(..))")
  30. public void aspectDebugLogAnnotation() {
  31. }
  32. /**
  33. * 针对前面 aspectAnalyzeAnnotation() 的配置
  34. */
  35. @Around("aspectAnalyzeAnnotation()")
  36. public void aroundJoinAspectAnalyze(final ProceedingJoinPoint joinPoint) throws Throwable {
  37. Object target = joinPoint.getTarget();
  38. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  39. AspectAnalyze aspectAnalyze = methodSignature.getMethod().getAnnotation(AspectAnalyze.class);
  40. long startTimeMillis = System.currentTimeMillis();
  41. joinPoint.proceed();
  42. if (aspectTraceListener != null) {
  43. aspectTraceListener.onAspectAnalyze(joinPoint, aspectAnalyze, methodSignature, System.currentTimeMillis() - startTimeMillis);
  44. }
  45. }
  46. /**
  47. * 针对前面 aspectDebugLogAnnotation() 或 activityOnCreatePointcut() 的配置
  48. */
  49. @Around("aspectDebugLogAnnotation() || activityOnCreatePointcut()")
  50. public void aroundJoinAspectDebugLog(final ProceedingJoinPoint joinPoint) throws Throwable {
  51. long startTimeMillis = System.currentTimeMillis();
  52. joinPoint.proceed();
  53. long duration = System.currentTimeMillis() - startTimeMillis;
  54. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  55. SourceLocation location = joinPoint.getSourceLocation();
  56. String message = String.format("%s(%s:%s) [%sms]", methodSignature.getMethod().getName(), location.getFileName(), location.getLine(), duration);
  57. if (aspectTraceListener != null) {
  58. aspectTraceListener.logger("AspectTrace", message);
  59. } else {
  60. Log.e("AspectTrace", message);
  61. }
  62. }
  63. public static void setAspectTraceListener(AspectTraceListener aspectTraceListener) {
  64. AnnotationAspectTrace.aspectTraceListener = aspectTraceListener;
  65. }
  66. public interface AspectTraceListener {
  67. void logger(String tag, String message);
  68. void onAspectAnalyze(ProceedingJoinPoint joinPoint, AspectAnalyze aspectAnalyze, MethodSignature methodSignature, long duration);
  69. }
  70. }

非侵入式:

以下几个常用场景

  1. package com.trackpoint;
  2. import android.util.Log;
  3. import android.widget.Toast;
  4. import com.trackpoint.annotation.AspectAnalyze;
  5. import org.aspectj.lang.JoinPoint;
  6. import org.aspectj.lang.ProceedingJoinPoint;
  7. import org.aspectj.lang.annotation.Around;
  8. import org.aspectj.lang.annotation.Aspect;
  9. import org.aspectj.lang.annotation.Before;
  10. import org.aspectj.lang.annotation.Pointcut;
  11. import org.aspectj.lang.reflect.MethodSignature;
  12. import org.aspectj.lang.reflect.SourceLocation;
  13. @SuppressWarnings("unused")
  14. @Aspect
  15. public class AspectTrace {
  16. private final String TAG = "AspectTrace";
  17. @Around("call(* android.widget.Toast.setText(java.lang.CharSequence))")
  18. public void handleToastText(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
  19. Log.d(TAG," start handleToastText");
  20. proceedingJoinPoint.proceed(new Object[]{"处理过的toast"}); //这里把它的参数换了
  21. Log.d(TAG," end handleToastText");
  22. }
  23. @Before("call(* android.widget.Toast.show())")
  24. public void changeToast(JoinPoint joinPoint) throws Throwable {
  25. Toast toast = (Toast) joinPoint.getTarget();
  26. toast.setText("修改后的toast");
  27. Log.d(TAG, " --> changeToast");
  28. }
  29. /**
  30. * 在MainActivity的所有生命周期的方法中打印log
  31. * @param joinPoint
  32. * @throws Throwable
  33. */
  34. @Before("execution(* android.app.Activity.**(..))")
  35. public void method(JoinPoint joinPoint) throws Throwable {
  36. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  37. String className = joinPoint.getThis().getClass().getSimpleName();
  38. Log.e(TAG, "class:" + className+" method:" + methodSignature.getName());
  39. }
  40. }
  1. @Aspect
  2. public class ViewAspect {
  3. private final String TAG = "ViewAspect";
  4. @Pointcut("execution(void android.view.View.OnClickListener.onClick(..))")
  5. public void onClickPointcut() {
  6. }
  7. @Pointcut("execution(* *.*onTouch(..))")
  8. public void onTouchPointcut() {
  9. Log.d(TAG,"onTouchPointcut");
  10. }
  11. @Around("onClickPointcut()")
  12. public void aroundJoinClickPoint(final ProceedingJoinPoint joinPoint) throws Throwable {
  13. Object target = joinPoint.getTarget();
  14. String className = "";
  15. if (target != null) {
  16. className = target.getClass().getName();
  17. }
  18. //获取点击事件view对象及名称,可以对不同按钮的点击事件进行统计
  19. Object[] args = joinPoint.getArgs();
  20. if (args.length >= 1 && args[0] instanceof View) {
  21. View view = (View) args[0];
  22. int id = view.getId();
  23. String entryName = view.getResources().getResourceEntryName(id);
  24. TrackPoint.onClick(className, entryName);
  25. }
  26. joinPoint.proceed();//执行原来的代码
  27. }
  28. }

遇到问题:

1.使用过程中经常对不上接口onTouch(..)

2.每次改变aspect代码需要clean项目

github demo代码:https://github.com/xingchongzhu/AspectJDemo

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/266742
推荐阅读
相关标签
  

闽ICP备14008679号