使用AspectJ
集成步骤:
1、AS配置Aspectj环境
2、配置使用ajc编译
4、定义注解
5、Aspect
6、使用
7、Example
AS配置Aspectj环境。Aspect目前最新版本为 1.8.10,AS中需要集成aspectjtool及aspectjrt并配置ajc编译,具体如下:
build.gradle(project)
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath "com.android.tools.build:gradle:${GRADLE_VERSION}" classpath "org.aspectj:aspectjtools:${ASPECT_VERSION}" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
build.gradle(app)
dependencies { compile "org.aspectj:aspectjrt:${ASPECT_VERSION}" } android.libraryVariants.all { variant -> LibraryPlugin plugin = project.plugins.getPlugin(LibraryPlugin) JavaCompile javaCompile = variant.javaCompile javaCompile.doLast { String[] args = ["-showWeaveInfo", "-1.5", "-inpath", javaCompile.destinationDir.toString(), "-aspectpath", javaCompile.classpath.asPath, "-d", javaCompile.destinationDir.toString(), "-classpath", javaCompile.classpath.asPath, "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator) ] def log = project.logger log.error("aspectj", "----------------------aspect ajc args-------------------" + Arrays.toString(args)) MessageHandler handler = new MessageHandler(true); new Main().run(args, handler) for (IMessage message : handler.getMessages(null, true)) { switch (message.getKind()) { case IMessage.ABORT: case IMessage.ERROR: case IMessage.FAIL: log.error message.message, message.thrown break; case IMessage.WARNING: case IMessage.INFO: log.info message.message, message.thrown break; case IMessage.DEBUG: log.debug message.message, message.thrown break; } } } }
定义注解
package com.xiaosw.aspectj.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p><br/>ClassName : {@link UserBehaviour}
* <br/>Description : 用户行为统计
* <br/>
* <br/>Author : xiaosw<xiaosw0802@163.com>
* <br/>Create date : 2017-03-21 11:11:16</p>
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface UserBehaviour {
String value() default "";
}
Aspect
package com.xiaosw.aspectj.aspacet;
import android.util.Log;
import com.xiaosw.aspectj.annotation.UserBehaviour;
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 java.lang.reflect.Method;
/**
* <p><br/>ClassName : {@link UserBehaviourAspacet}
* <br/>Description :
* <br/>
* <br/>Author : xiaosw<xiaosw0802@163.com>
* <br/>Create date : 2017-03-21 11:11:17</p>
*/
@Aspect
public class UserBehaviourAspacet {
/** @see UserBehaviourAspacet#getClass().getSimpleName() */
private static final String TAG = "UserBehaviourAspacet";
// 任意类任意方法任意参数使用UserBehaivour注解
private static final String METHOD_INPUTCUT = "execution(@com.xiaosw.aspectj.annotation.UserBehaviour * *(..))";
// 任意类任意构造方法使用UserBehaivour注解
private static final String CONSTRUCTOR_INPUTCUT = "execution(@com.xiaosw.aspectj.annotation.UserBehaviour *.new(..))";
// 普通方法切点
@Pointcut(METHOD_INPUTCUT)
public void methodAnnotatedWithUserBehaviour() {}
// 构造方法切点
@Pointcut(CONSTRUCTOR_INPUTCUT)
private void constructorAnnotatedWithUserBehaviour() {}
/**
* 同步方法不作为切点
*/
@Pointcut("execution(!synchronized * *(..))")
private void noSynchronized() {}
// @Before("methodAnnotatedWithUserBehaviour() || constructorAnnotatedWithUserBehaviour()")
// public void callBefore() {
// Log.e(TAG, "callBefore()");
// }
//
// @After("methodAnnotatedWithUserBehaviour() || constructorAnnotatedWithUserBehaviour()")
// public void callAfter() {
// Log.e(TAG, "callAfter()");
// }
// Advice
@Around("noSynchronized() && (methodAnnotatedWithUserBehaviour() || constructorAnnotatedWithUserBehaviour())")
public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
Log.e(TAG, "weaveJoinPoint: ");
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
if (method.isAnnotationPresent(UserBehaviour.class)) {
UserBehaviour userBehaviour = method.getAnnotation(UserBehaviour.class);
Log.e(TAG, "weaveJoinPoint: parsms = " + userBehaviour.value());
result = joinPoint.proceed();
} else {
Log.e(TAG, "weaveJoinPoint: method not instaceof UserBehaviour.class");
}
return result;
}
}
使用
@UserBehaviour("call testAop()")
private void testAop() {
Log.e(TAG, "call -----------------> testAop()");
}