我遇到了同样的问题。这就是我为解决它所做的一切。
根/主项目
在您的根项目中添加包含编织类所必需的 ajc 编译器的 AspectJ 工具。 (您也可以将其添加到您的库的 build.gradle 文件中,但最好将其添加到此处,因为您将创建以适应您的库的 gradle 插件将使用 ajc。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'org.aspectj:aspectjtools:1.8.5'
}
图书馆项目
在你的库的 build.gradle 文件中确保它看起来像这样。主要添加的是顶部的 import 语句和 android 构建属性下的代码。
import com.android.build.gradle.LibraryPlugin
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
apply plugin: 'com.android.library'
dependencies {
compile 'org.aspectj:aspectjrt:1.8.5'
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
android.libraryVariants.all { variant ->
LibraryPlugin plugin = project.plugins.getPlugin(LibraryPlugin)
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", android.bootClasspath.join(File.pathSeparator)
]
MessageHandler handler = new MessageHandler(true);
new Main().run(args, handler)
def log = project.logger
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:
case IMessage.INFO:
log.info message.message, message.thrown
break;
case IMessage.DEBUG:
log.debug message.message, message.thrown
break;
}
}
}
}
所以在编译项目时,ajc(AspectJ 的编织器)命令编译并编织 AspectJ 和 Java 源代码和 .class 文件,生成与任何 Java VM 兼容的 .class 文件。
为此,任务需要有关您的库的参数。这就是创建 args 变量的原因。
String[] args = [
"-showWeaveInfo",
"-1.5",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", android.bootClasspath.join(File.pathSeparator)
]
然后将创建的消息处理程序简单地传递给 ajc 以累积在 ajc 编译/编织类时发生的事件的消息。然后它被传递给项目记录器,然后输出 ajc 产生的任何重要错误或警告。例如,如果一个切入点不能被通知引用,它将被检测到并显示在 gradle 控制台中。
所以上面描述的所有事情基本上都在这里发生。 args 和消息处理程序被传递到 ajc(AspectJ 编译器)的 Main 函数的位置。
MessageHandler handler = new MessageHandler(true);
new Main().run(args, handler)
def log = project.logger
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
Gradle 插件
您的库的切入点/建议没有被触发,因为您的目标是应用程序模块,而 Aspects 仅通过 com.uphyca.gradle:gradle-android-aspectj-plugin AspectJ 插件被编织到您的库模块中。因此,为了将库的 Aspects 编织到应用程序的模块中,您必须为您的项目创建一个 gradle 插件。所以你定义为你的目标是你的问题是不可能的,这是唯一可以做到的方法。
这就是插件的外观。 (插件是在 groovy 中完成的)。
插件的build.gradle
apply plugin: 'groovy'
targetCompatibility = JavaVersion.VERSION_1_7
sourceCompatibility = JavaVersion.VERSION_1_7
dependencies {
compile gradleApi()
compile localGroovy()
compile 'com.android.tools.build:gradle:1.1.0-rc3'
compile 'org.aspectj:aspectjtools:1.8.5'
compile 'org.aspectj:aspectjrt:1.8.5'
}
然后是实际的类。
import com.android.build.gradle.AppPlugin
import com.android.build.gradle.LibraryPlugin
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
import org.gradle.api.Plugin
import org.gradle.api.Project
public class YourPlugin implements Plugin<Project> {
@Override void apply(Project project) {
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 {
compile 'com.name:example:1.0'
// TODO this should come transitively
compile 'org.aspectj:aspectjrt:1.8.5'
}
variants.all { variant ->
variant.dex.doFirst {
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;
}
}
}
}
}
}
我知道这可能看起来很多,但复制和粘贴很多,因为解决方案保持不变。如果您仔细查看该类,您的库模块中正在执行的相同操作现在正在应用于您的应用程序模块。
您要做的主要修改是通过此处完成的插件将您的库模块添加到项目的依赖项中。
project.dependencies {
compile 'com.letz:example-library:1.0'
// TODO this should come transitively
compile 'org.aspectj:aspectjrt:1.8.5'
}
为了让您的库在开发时可供插件使用,您必须确保将其部署到本地 maven 存储库。这可以通过将此插件(https://github.com/dcendents/android-maven-gradle-plugin)应用到您的库模块并运行gradle install 任务来完成。
最后的步骤
所有这些都完成后,您可以通过将其添加到它的 build.gradle 文件中,将其应用到示例应用进行测试
buildscript {
repositories {
mavenCentral()
//Only necessary when developing locally.
mavenLocal()
}
dependencies {
classpath 'com.letz:example-plugin:1.0'
}
}
apply plugin: 'example-plugin'
完成后,您的库将可供应用使用,因为一旦应用插件,它就会被添加到项目中。
如果事情仍然令人困惑,那么你很幸运,因为我实施此解决方案的项目在 Github 上,因此你可以分叉它,复制插件的项目并进行必要的更改。
该项目名为 Flender,它用于注释需要连接检查的方法。这是链接https://github.com/jd-alexander/flender
希望这个答案有帮助。