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 都需要添加以上的编织脚本,然后会引发相应的错误。可能的接入错误看这篇

组件接入

 

posted @ 2020-12-08 11:55  Spiderman.L  阅读(360)  评论(0编辑  收藏  举报