Android Aspectj 接入错误记录

接入错误

1. org.aspectj.apache.bcel.classfile.ClassFormatException

org.aspectj.apache.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 18

遇到这个问题是添加Aspectj版本号比较低的原因,更新到最新版本即可。目前是2020/12/8 版本号1.9.6 。最新版本号可以去官网查看 

dependencies {
     classpath "com.android.tools.build:gradle:4.0.2"
     classpath 'org.aspectj:aspectjtools:1.9.5'
}
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'org.aspectj:aspectjrt:1.9.6'
}

2.  Default interface methods are only supported starting with Android N (--min-api 24)

Default interface methods are only supported starting with Android N (--min-api 24): void org.aspectj.lang.ProceedingJoinPoint.stack$AroundClosure(org.aspectj.runtime.internal.AroundClosure)
Stack trace:
com.android.tools.r8.a: Default interface methods are only supported starting with Android N (--min-api 24): void org.aspectj.lang.ProceedingJoinPoint.stack$AroundClosure(org.aspectj.runtime.internal.AroundClosure)
    at com.android.tools.r8.dex.r.a(:60)

这个其实是因为 java8 才支持静态接口方法的原因,所以我们需要指定 module 编译 javaVersion。

android {
    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

添加以上配置即可解决。

3 . java.lang.NoSuchMethodError: No static method aspectOf()

java.lang.NoSuchMethodError: No static method aspectOf()

出现错误的根本原因是代码未织入成功。可能造成的原因是

  1. 未在对应 module build.gradle下添加对应编织脚本。
  2. @Aspect 修饰的切片未指定为 public 。

解决方式:

import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
final def log = project.logger
// 这个是 application module
//android.applicationVariants.all{...}
// 这个是 library module
android.libraryVariants.all{ variant ->
    if (!variant.buildType.isDebuggable()) {
        log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")
        return
    }

    JavaCompile javaCompile = variant.javaCompiler
    javaCompile.doLast {
        String[] args = ["-showWeaveInfo",
                         "-1.8",
                         "-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
            }
        }
    }
}

在 module build.gradle 下添加以上编织脚本即可正常运行。如果不想每个 module下都天加这样的编织脚本,我们可以自定义 gradle plugin。

posted @ 2020-12-08 10:04  Spiderman.L  阅读(1667)  评论(0编辑  收藏  举报