記錄下aspectj在Android中的使用

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

    }
}

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容