Tôi cũng gặp vấn đề tương tự. Đây là tất cả những gì tôi đã làm để giải quyết nó.
Root/Main Project
Trong dự án gốc của bạn thêm các công cụ AspectJ có chứa trình biên dịch AJC đó là cần thiết cho dệt lớp học của bạn. (Bạn cũng có thể thêm video này vào tập tin build.gradle của thư viện của bạn, nhưng nó tốt hơn để thêm nó ở đây là plugin gradle rằng bạn sẽ được tạo để phù hợp với thư viện của bạn sẽ sử dụng AJC.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'org.aspectj:aspectjtools:1.8.5'
}
Dự án Thư viện
Trong file build.gradle thư viện của bạn đảm bảo rằng nó trông giống như tương tự này để này. các bổ sung chính là những điều khoản về nhập khẩu ở phía trên và mã bên dưới xây dựng thuộc tính 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;
}
}
}
}
Vì vậy, những gì đang xảy ra là khi dự án đang được biên dịch lệnh ajc (WeaverJ's weaver) biên dịch và dệt các tệp AspectJ và Java và các tệp .class, tạo các tệp .class tương thích với bất kỳ máy ảo Java nào.
Để điều này xảy ra, tác vụ cần đối số về thư viện của bạn. Đó là lý do để tạo biến 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)
]
Sau đó, trình xử lý tin nhắn được tạo chỉ đơn giản được chuyển tới ajc để tích lũy các thông báo sự kiện đang diễn ra trong khi ajc đang biên soạn/dệt các lớp. Sau đó, nó được chuyển đến một logger dự án và sau đó xuất ra bất kỳ lỗi hoặc cảnh báo quan trọng nào mà ajc đã tạo ra. Ví dụ, nếu một điểm cắt không thể được tham chiếu bởi một lời khuyên nó sẽ được phát hiện và hiển thị trong bảng điều khiển gradle.
Vì vậy, tất cả những gì được mô tả ở trên về cơ bản đang diễn ra ngay tại đây. Trong trường hợp trình xử lý thông điệp và args được truyền đến hàm chính của ajc (trình biên dịch AspectJ).
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 Plugin
Các pointcuts/lời khuyên của thư viện của bạn đã không được kích hoạt bởi vì bạn nhắm mục tiêu các module ứng dụng trong khi khía cạnh được chỉ được dệt vào mô-đun của thư viện của bạn với AspectJ Plugin com.uphyca.gradle:gradle-android-aspectj-plugin
. Vì vậy, để cho các khía cạnh của thư viện của bạn được dệt vào mô-đun ứng dụng của bạn, bạn phải tạo một plugin gradle cho dự án của bạn. Vì vậy, những gì bạn đã xác định là mục tiêu của bạn là câu hỏi của bạn là không thể, đây là cách duy nhất nó có thể được thực hiện.
Đây là giao diện của plugin. (Plugin được thực hiện trong groovy).
Plugin của 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'
}
Sau đó, lớp thực tế.
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;
}
}
}
}
}
}
Tôi biết điều này có vẻ như rất nhiều nhưng không sao chép và dán vì giải pháp vẫn giữ nguyên. Nếu bạn nhìn kỹ vào lớp, những thứ tương tự đang được thực hiện trong mô-đun thư viện của bạn hiện đang được áp dụng cho mô-đun của ứng dụng. Việc sửa đổi chính bạn sẽ làm điều này là thêm mô-đun thư viện của bạn vào các phụ thuộc của dự án thông qua plugin được thực hiện ở đây.
project.dependencies {
compile 'com.letz:example-library:1.0'
// TODO this should come transitively
compile 'org.aspectj:aspectjrt:1.8.5'
}
Để thư viện của bạn khả dụng với plugin trong khi phát triển, bạn phải đảm bảo rằng thư viện được triển khai tới kho lưu trữ maven cục bộ của bạn. Điều này có thể được thực hiện bằng cách áp dụng plugin này (https://github.com/dcendents/android-maven-gradle-plugin) vào mô-đun thư viện của bạn và chạy tác vụ gradle install
.
cuối cùng bước
Khi tất cả điều đó được thực hiện thì bạn có thể áp dụng nó vào một ứng dụng mẫu để thử nghiệm bằng cách thêm này để nó build.gradle tập tin
buildscript {
repositories {
mavenCentral()
//Only necessary when developing locally.
mavenLocal()
}
dependencies {
classpath 'com.letz:example-plugin:1.0'
}
}
apply plugin: 'example-plugin'
Khi đã xong thư viện của bạn sẽ có sẵn cho ứng dụng vì ứng dụng sẽ được thêm vào dự án khi plugin đã được áp dụng.
Nếu mọi thứ vẫn còn khó hiểu, bạn sẽ gặp may mắn vì dự án tôi đã triển khai giải pháp này là trên Github để bạn có thể chia nhỏ nó, sao chép dự án của plugin và thực hiện các thay đổi cần thiết.
Dự án được gọi là Flender và được sử dụng để chú thích các phương thức yêu cầu kiểm tra kết nối. Đây là liên kết https://github.com/jd-alexander/flender
Hy vọng câu trả lời này sẽ hữu ích.