aspectj在Spring中引入AOP依賴就可以使用,但是在Android中,需要手動(dòng)加一點(diǎn)點(diǎn)配置,具體如下:
項(xiàng)目根目錄的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'
}
//下面不知道什么意思,抄下來的(注意:如果是組件化開發(fā),aspectj放在單獨(dú)的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
}
}
}
}
組件化開發(fā)中,不可能讓每一個(gè)使用aspectj的module都如上集成一遍,更好的方式是在一個(gè)module(新建Android module,而不是java module)中引入aspectj,其他module再依賴該module,則該module的build.gradle應(yīng)該這樣寫:
...
dependencies {
...
// 添加aspectj的依賴,使用compile是為了讓其他module也可以使用該module中的aspectj的相關(guān)功能
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
}
}
}
}
之前配置環(huán)境一直出問題,這下總于弄好了,感謝:https://blog.csdn.net/qby_nianjun/article/details/79182346,環(huán)境配置好后開始上代碼。
示例:對所有控件的點(diǎn)擊事件做切面,判斷如果上次0.5s內(nèi)有過點(diǎn)擊,則不執(zhí)行點(diǎn)擊事件
// 1.聲明該類是做切面聲明和處理的類
@Aspect
public class ClickAspect {
//聲明切點(diǎn)為:View的點(diǎn)擊事件,該方法的名字隨便取,但是要和下面@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 {
//做點(diǎn)擊間隔判斷
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>>>", "兩次點(diǎn)擊時(shí)間間隔太短了,拒絕點(diǎn)擊!");
}
}
}