赞
踩
做一个学习记录:
Android中的AOP编程
Android之AOP
Android Studio 中自定义 Gradle 插件
看AspectJ在Android中的强势插入
jarryleo / MagicBuriedPoint
(1)用自定义注解修饰切入点,精确控制切入点,属于侵入式;
(2)不需要在切入点代码中做任何修改,属于非侵入式。
侵入式用法,一般会使用自定义注解,以此作为选择切入点的规则。
非侵入式,就是不需要使用额外的注解来修饰切入点,不用修改切入点的代码。
一般情况下我们会新建一个独立模块提供给其它项目接入使用,如下图TrackPoint模块
build.gradle模块配置
两种方式:1.apply plugin: 'android-aspectjx'
2.implementation 'org.aspectj:aspectjrt:1.8.+'
- @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);
- }
- }
以下几个常用场景
- 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();//执行原来的代码
- }
- }
1.使用过程中经常对不上接口onTouch(..)
2.每次改变aspect代码需要clean项目
github demo代码:https://github.com/xingchongzhu/AspectJDemo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。