一些需要知道的:

  1. Aspectj在android中,都是通过注解完成,如@AspectJ,@Pointcut....。
  2. Aspectj的代码需要专门的编译器编译才能使用,在android中,通过添加一些gradle代码,来达到,这篇文章有介绍。
  3. 具体学习aspectj可以参考这里
  4. 遇到aspectj无法匹配到方法,或者无效时,请先查看message编译信息,以此定位问题。常见的如 invalid pointcut xxxx。


    编译信息
  5. AspectjX会和带有TransForm功能的插件相冲突,常见的有: retroLambda,butterKnife好像也是。

几种引入aspectj的方法

1. 依赖aspectj

这种方法并不在此篇文章讲述范围中,如果需要,可以点击这里。

2. 使用沪江aspectjX插件

沪江公司出的一款aspect插件,只需要在 项目.gradle文件中添加

build.gradle(project)dependencies {        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.10'        }bulid.gradle(相关 module)apply plugin: 'android-aspectjx'

之后你就可以愉快的使用AspectJ进行切面代码编写了。
如果遇到gradle报错,但是原因是空,如:

app:transformClassesWithRetrolambdaForDebug error

那么请使用下面的方法,这个错误没有办法解决,它的原因是:Transform 插件冲突。可以查看这里

一些问题

每次都需要在gradle中配置一大段代码,来使gradle支持Aspectj代码的编译,有没有简单的办法?

这问题好解决,封装呗,也就是自定义一个gradle插件来专门干这个事情。

  1. 创建一个module(java),module名字必须是buildsrc,然后删除java文件夹,只留下src/main。(不明白可以直接看下面的包结构)
  2. 在src/main文件夹下新建一个目录为 groovy,然后在groovy中,创建一个包(包名无所谓,只是最后你其他模块应用这个插件时候,是根据包名应用)
  3. 打开此module的gradle文件,全删,然后放入如下代码(记得同步)
apply plugin: 'groovy'dependencies {    compile gradleApi()    compile localGroovy()    compile 'com.android.tools.build:gradle:2.3.1'    compile 'org.aspectj:aspectjtools:1.8.10'    compile 'org.aspectj:aspectjrt:1.8.10'}repositories {    jcenter()}
  1. 在刚才的包中创建一个文件,后缀名为groovy,代码:
package com.hxh.aspjpluginimport com.android.build.gradle.AppPluginimport com.android.build.gradle.LibraryPluginimport org.aspectj.bridge.IMessageimport org.aspectj.bridge.MessageHandlerimport org.aspectj.tools.ajc.Mainimport org.gradle.api.Pluginimport org.gradle.api.Projectimport org.gradle.api.tasks.compile.JavaCompilepublic class AspectjPlugin implements Plugin {    void apply(Project project) {        //得到当前module的插件类型,是application还是lib        System.out.println("========================");        System.out.println("Aspject开始编译!");        System.out.println("========================");        def hasApp = project.plugins.withType(AppPlugin)        def hasLib = project.plugins.withType(LibraryPlugin)        if (!hasApp && !hasLib) {            throw new IllegalStateException("'android' or 'android-library' plugin required.")        }        final def log = project.logger        final def variants        if (hasApp) {            variants = project.android.applicationVariants        } else {            variants = project.android.libraryVariants        }        project.dependencies {            // TODO this should come transitively            compile 'org.aspectj:aspectjrt:1.8.6'        }        variants.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", 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;                    }                }            }        }        System.out.println("========================");        System.out.println("Aspject编译结束!");        System.out.println("========================");    }}
  1. clean -》 make 不出意外,你就能看到编译信息了
编译信息
  1. 最后预览一下整体结构
buildsrc包结构
  1. 其他模块依赖这个插件
apply plugin: com.hxh.aspjplugin.AspectjPlugin

当然,自定义gradle插件并不止这一种方法,你可以参考这里,我使用的这篇文章中第二种方法。

aspj无效,或者无法匹配到方法
  1. 检查表达式是否正确,如果你的表达式是这样的(它不是错误的):
    //应用了DataSave注解,并且有个参数为ann    public final String method_piex1 = "execution(@routerlib.hxh.com.corelib_annotation1.annotation.DataSave * *(..)) && @annotation(ann)";    //上面的表达式并不是错误的,但是在你仔细检查表达式没发现问题的话,那么你可以这样描述你的表达式    public final String method_piex = "@within(routerlib.hxh.com.corelib_annotation1.annotation.DataSave) || @annotation(routerlib.hxh.com.corelib_annotation1.annotation.DataSave)";
  1. 是否引入了aspectj的依赖并且添加了编译aspectj文件的代码 。或者插件(使用aspectjX时候)

当如上都否定时候,如果你使用的是自定义gradle插件方法,而且当前自定义的gradle插件是一种可发布状态的,那么请改为【针对当前项目的gradle插件】,可以参考这里。

使用AspectjX,然后编译一直不通过,而且错误信息还是空

上面有相关解释,所以,请更换引入aspectj的方式。

使用JDK1.8 的问题

当你遇到,编译正常通过,但是aspectj的代码就是不执行的时候,错误的信息为:

Invalid byte tag in constant pool 18

如果你当前应用的jdk版本为1.8,那么你要这么做

  • 检查你的aspectj 的版本,让其为1.8.10(包含)以上
apply plugin: 'groovy'dependencies {    compile gradleApi()    compile localGroovy()    compile 'com.android.tools.build:gradle:2.3.1'    compile 'org.aspectj:aspectjtools:1.8.10'//这两句    compile 'org.aspectj:aspectjrt:1.8.10'//这两句}repositories {    jcenter()}
编译出现 No such property: project for class: com.android.build.gradle.LibraryPlugin的问题

这是因为Gradle 2.3+ 后,配置变了

   "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]                log.debug "ajc args: " + Arrays.toString(args)变更为:   "-bootclasspath",android.bootClasspath.join(File.pathSeparator)]                log.debug "ajc args: " + Arrays.toString(args)

持续更新中....

更多相关文章

  1. android 一个很漂亮的控件ObservableScrollView(含片段代码和源码
  2. Android(安卓)利用addView 动态给Activity添加View组件
  3. 第一行代码读书笔记 Kotlin Android
  4. Android(安卓)proguard混淆编译的问题
  5. [转]Android(安卓)Music和第三方应用
  6. Android(安卓)画图之抗锯齿
  7. Android(安卓)Studio重构之路,我们重新来了解一下Google官方的And
  8. Launcher桌面点击&长按&拖动事件处理流程分析
  9. Android(安卓)init.c简析

随机推荐

  1. android ddms查看线程
  2. #Android(安卓)Day2
  3. Android启动Service的两种方式之startSer
  4. Android(安卓)屏幕实现上下翻转
  5. 拥抱Android:编译nginx搭建移动平台
  6. Android学习总结--第一周
  7. Android——Messenger
  8. Android(安卓)常见的五大布局
  9. Android下的配置管理之道之高通拆仓
  10. android布局layout中的一些属性