Android Aspectj 接入 - 非组件
前言
Android 中接入 Aspectj 目前常用的方式有两种,一种是项目非组件的方式接入,即我们在使用切片的 module 下加入编织脚本。另一种方式是组件的方式接入,就是以 Gradle Plugin 的方式接入。对于使用的 module ,直接 apply 我们定义的 Plugin 就行。我个人比较推荐第二种,因为只需要维护一个脚本即可。非组件的方式接入,在涉及编织的 module 下都需加入编织脚本。由于脚本依赖于 Gradle ,所以接入前说明一下本文的环境,于不同Gradle Version 可能需要稍作修改。
接入先说一下当前环境:
- Android Studio 4.0.1
-
Gradle Version 6.1.1
- Android Gradle Plugin Version 4.0.2
非组件接入
1. 在 Project bulid.gradle 中添加如下:
buildscript { ... dependencies { ... classpath 'org.aspectj:aspectjtools:1.9.5' } }
2. 在 Module build.gradle 中添加如下:
> 指定编织 Java Version
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
> 添加 Aspectj 依赖
implementation 'org.aspectj:aspectjrt:1.9.6'
> 添加编织脚本,放在最后即可。注意下面编织是针对 application module的,如果是 Library Module 下面这个行代码中的 applicationVariants 应该替换为 libraryVariants 。
import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main final def log = project.logger //注意:如果是 Library Module 下面这个行代码中的 applicationVariants 应该替换为 libraryVariants 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.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 都需要添加以上的编织脚本,然后会引发相应的错误。可能的接入错误看这篇
组件接入