Java 带有android库的Aspectj
我有一个使用方面的库,可以通过maven获得,现在我正试图在android应用程序中使用该库 如果我在应用程序gradle文件中包含,一切都正常,但是 我的目标是将Java 带有android库的Aspectj,java,android,aop,aspectj,android-library,Java,Android,Aop,Aspectj,Android Library,我有一个使用方面的库,可以通过maven获得,现在我正试图在android应用程序中使用该库 如果我在应用程序gradle文件中包含,一切都正常,但是 我的目标是将classpath'com.uphyca.gradle:gradle android aspectj插件:0.9.+'和apply插件:'android aspectj'(插件需要)提取到my.lib gradle文件中,而不是在我的应用程序中声明 可能吗 应用程序梯度文件: 目标: 应用程序梯度文件: my.lib渐变文件: 我也
classpath'com.uphyca.gradle:gradle android aspectj插件:0.9.+'
和apply插件:'android aspectj'
(插件需要)提取到my.lib gradle文件中,而不是在我的应用程序中声明
可能吗
应用程序梯度文件:
目标: 应用程序梯度文件: my.lib渐变文件:
我也有同样的问题。这就是我为解决这个问题所做的一切 根/主项目 在根项目中添加AspectJ工具,该工具包含编织类所需的ajc编译器。(您也可以将其添加到库的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文件中,确保它看起来与此类似。主要添加的是顶部的导入语句和android build属性下面的代码
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的weaver)命令编译并编织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产生的任何重要错误或警告。例如,如果一个切入点不能被通知i引用,则t将被检测并显示在gradle控制台中。
因此,上面所描述的一切基本上都发生在这里,其中args和消息处理程序被传递给ajc(AspectJ编译器)的主函数
Gradle插件
你的库的切入点/建议没有被触发,因为你的目标是应用程序模块,而Aspect只是通过com.uphyca.gradle:gradle android aspectj插件
aspectj插件编织到你库的模块中。因此,为了让你库的Aspect被编织到你的应用程序模块中,你必须为你的项目创建一个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;
}
}
}
}
}
}
要使您的库在开发时可用于插件,您必须确保它已部署到本地maven存储库中。这可以通过将此插件()应用到库模块并运行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,用于注释需要连接检查的方法
希望这个答案有帮助
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
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'
}
buildscript {
repositories {
mavenCentral()
//Only necessary when developing locally.
mavenLocal()
}
dependencies {
classpath 'com.letz:example-plugin:1.0'
}
}
apply plugin: 'example-plugin'