Android使用Aspectj(AOP)
使用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()"); }