记录下aspectj在Android中的使用

aspectj在Spring中引入AOP依赖就可以使用,但是在Android中,需要手动加一点点配置,具体如下:
项目根目录的build.gradle

buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.3"
        //添加这两行代码
        classpath "org.aspectj:aspectjtools:1.8.9"
        classpath "org.aspectj:aspectjweaver:1.8.9"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
}

app下的build.gradle

...
dependencies {
    ...
    // 添加aspectj的依赖
    implementation 'org.aspectj:aspectjrt:1.8.13'
}
//下面不知道什么意思,抄下来的(注意:如果是组件化开发,aspectj放在单独的module中,则是另一种写法)
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main

final def log = project.logger
final def variants = project.android.applicationVariants

variants.all { variant ->
    if (!variant.buildType.isDebuggable()) {
        log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")
        return
    }

    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)]
        log.debug "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:
                    log.warn message.message, message.thrown
                    break
                case IMessage.INFO:
                    log.info message.message, message.thrown
                    break
                case IMessage.DEBUG:
                    log.debug message.message, message.thrown
                    break
            }
        }
    }
}

组件化开发中,不可能让每一个使用aspectj的module都如上集成一遍,更好的方式是在一个module(新建Android module,而不是java module)中引入aspectj,其他module再依赖该module,则该module的build.gradle应该这样写:

...
dependencies {
     ...
    // 添加aspectj的依赖,使用compile是为了让其他module也可以使用该module中的aspectj的相关功能
    compile 'org.aspectj:aspectjrt:1.8.13'
}

import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main

android.libraryVariants.all { variant ->
    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", android.bootClasspath.join(
                File.pathSeparator)]

        MessageHandler handler = new MessageHandler(true)
        new Main().run(args, handler)

        def log = project.logger
        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
            }
        }
    }
}

之前配置环境一直出问题,这下总于弄好了,感谢:https://blog.csdn.net/qby_nianjun/article/details/79182346,环境配置好后开始上代码。
示例:对所有控件的点击事件做切面,判断如果上次0.5s内有过点击,则不执行点击事件

// 1.声明该类是做切面声明和处理的类
@Aspect
public class ClickAspect {
    //声明切点为:View的点击事件,该方法的名字随便取,但是要和下面@Around()中的value保持一致
    @Pointcut("execution(void android.view.View.OnClickListener.onClick(..))")
    public void viewClickPointCut(){}

    long lastClickTime = 0L;
    @Around("viewClickPointCut()")
    public void dealViewClickPointCut(ProceedingJoinPoint joinPoint) throws Throwable {
        //做点击间隔判断
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastClickTime > 500) {
            lastClickTime = currentTime;
            Log.e("aspect>>>", "before view clicked");
            Object result = joinPoint.proceed();
            Log.e("aspect>>>", "after view clicked");
        } else {
            Log.e("aspect>>>", "两次点击时间间隔太短了,拒绝点击!");
        }

    }
}

Demo地址:https://gitee.com/luxingxing/aspectjdemo

你可能感兴趣的:(记录下aspectj在Android中的使用)