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()");
}

  

 

posted @ 2017-03-21 16:03  w愿得一人心  阅读(680)  评论(0编辑  收藏  举报