记录下aspectj在Android中的使用
2021-10-13 本文已影响0人
飞奔吧牛牛
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>>>", "两次点击时间间隔太短了,拒绝点击!");
}
}
}