【问题标题】:Android AspectJ with Gradle in multimodule project多模块项目中带有 Gradle 的 Android AspectJ
【发布时间】:2014-06-06 06:34:47
【问题描述】:

有没有办法将 aspectJ 切入点从库模块应用到整个项目?这意味着我需要将库附加到现有项目,并且它必须拦截来自主项目的方法调用及其所有依赖项(也包括 Android SDK 方法) 现在我试图通过 build.gradle 中的脚本来做到这一点:

android.libraryVariants.all { variant ->

variant.javaCompile.doLast {
// Find the android.jar and add to iajc classpath
    def androidSdk = android.adbExe.parent + "/../platforms/" + android.compileSdkVersion +    "/android.jar"
    println 'Android SDK android.jar path: ' + androidSdk

    def iajcClasspath;
    iajcClasspath = androidSdk;


    project.rootProject.allprojects.each { proj ->
        if (proj.configurations.hasProperty("compile"))
            iajcClasspath += ":" + proj.configurations.compile.asPath
        // handle aar dependencies pulled in by gradle (Android support library and etc)
        tree = fileTree(dir: "${proj.buildDir}/exploded-aar", include: '**/classes.jar')
        tree.each { jarFile ->
            iajcClasspath += ":" + jarFile
        }
    }
    println 'Classpath for iajc: ' + iajcClasspath
    ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
    println 'ajctPath : ' + configurations.ajc.asPath.toString()
    println 'aspectPath : ' + configurations.aspects.asPath.toString()
    println 'inpath : ' + configurations.ajInpath.asPath.toString()
    ant.iajc(
            source: sourceCompatibility,
            target: targetCompatibility,
            fork: true,
            destDir: "${project.buildDir}/classes/${variant.dirName}",
            aspectPath: configurations.aspects.asPath,
            inpath: configurations.ajInpath.asPath,
            sourceRootCopyFilter: "**/*.java",
            classpath: iajcClasspath
    ) {
        sourceroots {
            android.sourceSets.main.java.srcDirs.each {
                pathelement(location: it.absolutePath)
            }
// Build config file
            pathelement(location: "${project.buildDir}/source/buildConfig/${variant.dirName}")
// Android resources R.***
            pathelement(location: "${project.buildDir}/source/r/${variant.dirName}")
        }
    }
}
}

但切入点仅适用于从此模块调用的方法。此外,即使我将脚本移动到 main build.gradle,并将 android.libraryVariants 替换为 android.applicationVariants,切入点也不适用于附加的 .jar 库和模块,但适用于 gradle 依赖项(例如 compile 'com.googlecode. mp4parser:isoparser:1.0.1',例如)。

如果没有办法用 AspectJ 做到这一点,也许还有其他方法可以从项目库中拦截所有项目中的方法调用?最重要的是主模块代码不能有任何变化,就在库中。

【问题讨论】:

    标签: android module gradle aspectj


    【解决方案1】:

    从antajcTask阅读文档后,我终于用我的gradle插件GradleAndroidAspectJPlugin实现了。

    我使用 iajc 类路径和 inpath 属性来指定哪些类(jar)将被编译为类路径或将从 aspectj 编译器重新编译。

    def aopTask = project.task("compile${buildTypeName}AspectJ") {
                    doFirst {
                        project.configurations.aspectsInPath.each {
                            aspectsInPaths.add(it);
                            aspectsInPathsAbsolute.add(it.absolutePath);
                        }
                    }
    
                    doLast {
                        ant.taskdef(
                                resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties",
                                classpath: project.configurations.aspectjTaskClasspath.asPath
                        )
                        ant.iajc(
                                source: project.android.compileOptions.sourceCompatibility,
                                target: project.android.compileOptions.targetCompatibility,
                                fork: "true",
                                destDir: variant.javaCompile.destinationDir,
                                bootClasspath: project.android.bootClasspath.join(File.pathSeparator),
                                inpathDirCopyFilter: "java/**/*.class"
                        ) {
                            classpath {
                                variant.javaCompile.classpath.each {
                                    if (!aspectsInPathsAbsolute.contains(it)) {
                                        pathElement(location: it)
                                    }
                                }
                            }
                            inpath {
                                pathElement(location: copyDir)
                                aspectsInPaths.each {
                                    if (!it.name.startsWith("aspectjrt")) {
                                        pathElement(location: it)
                                    }
                                }
                            }
                        }
                    }
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 2019-07-02
      • 2016-06-11
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多