Parceler 和 Lombok 不能一起工作?
Parceler and Lombok not working together?
对于我的 android 应用程序,我使用了 parceler 库和 lombok 库。
这些是我的注释 class:
@Table
@ToString
@Getter
@NoArgsConstructor
@Parcel
public class MyClass {
然而,在 gradle 构建期间,Parceler 抱怨没有默认的空构造函数。那么这是否意味着它不识别 @NoArgsConstructor
注释并且这两个根本不能一起工作?因为例如SugarORM 没有问题。或者我只是错过了什么?
这涉及 Lombok 如何将代码添加到您的 class。 Lombok 在 Java 注释处理器中使用 known trick 将代码添加到您的 class。此添加的代码在注释处理器轮次期间对 Parceler 不可见,并且使添加的无参数构造函数对 Parceler 未知。
我建议手动添加无参数构造函数,用 @ParcelConstructor
注释现有构造函数(我假设你有一个)或考虑使用具有 @Parcelable
注释.
我们最近有一个 issue/question 关于这个:https://github.com/johncarl81/parceler/issues/177
在构建空对象的静态方法上使用@ParcelFactory:
@Builder
public class MyClass {
@ParcelFactory
static MyClass fromParcel() {
return builder().build();
}
}
这个技巧可以与 Jackson 和其他库一起使用,允许您在构造函数之外注释静态工厂方法。
编辑: 在我做了一些清理后初始解决方案失败了,而且它不适用于 Proguard。请参阅下面更新的解决方案。
为了解决这个问题,我必须创建自己的自定义注释处理器。该处理器的想法是确保 Lombok 和 Parceler 使用的处理器的处理器顺序。
以下是我解决此问题所遵循的步骤:
步骤 1
在根项目下创建一个新的 Java 模块。任意命名,例如 parceler-lombok
,使用您选择的任何 class name/package。
步骤 2
添加 lombok 和 Parceler 注释 classes 作为对新模块的依赖,并设置源兼容性。
//File: parceler-lombok/build.gradle
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'org.projectlombok:lombok:1.16.16'
compile 'org.parceler:parceler:1.1.9'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
步骤 3
在模块的主源文件夹中创建以下目录:src/main/resources/META-INF/services
步骤 4
在上面的目录中创建一个名为 javax.annotation.processing.Processor
的文件。
步骤 5
编辑文件,添加以下行。
lombok.launch.AnnotationProcessorHider$AnnotationProcessor
lombok.launch.AnnotationProcessorHider$ClaimingProcessor
org.parceler.ParcelAnnotationProcessor
这是您的模块中所有可用注释处理器的声明。该顺序表明 Lombok 注释处理器应该在 parceler 的
之前加载
步骤 6
现在我们有了 "custom annotation processor",回到您的主应用程序模块,在应用程序的 build.gradle 文件中,执行以下操作:
- 移除lombok依赖(annotatorProcessor,提供或编译)指令
- 删除 parceler annotationProcessor 依赖项(即
org.parceler:parceler
),保持 API 依赖项不变。
- 现在将您的自定义注释处理器添加为依赖项
- 最后,确保 Java 1.7 兼容性
请参阅以下片段:
//File: app/build.gradle
android {
//...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
//...
}
dependencies {
// ...
//Remove these ones
//provided 'org.projectlombok:lombok:1.16.16'
//annotationProcessor 'org.parceler:parceler:1.1.9'
//leave parceler API
compile 'org.parceler:parceler-api:1.1.9'
provided project(':parceler-lombok')
}
使用 provided 可确保注解处理器 class 不会与您的应用捆绑在一起。
以下文章很有帮助:
对于我的 android 应用程序,我使用了 parceler 库和 lombok 库。
这些是我的注释 class:
@Table
@ToString
@Getter
@NoArgsConstructor
@Parcel
public class MyClass {
然而,在 gradle 构建期间,Parceler 抱怨没有默认的空构造函数。那么这是否意味着它不识别 @NoArgsConstructor
注释并且这两个根本不能一起工作?因为例如SugarORM 没有问题。或者我只是错过了什么?
这涉及 Lombok 如何将代码添加到您的 class。 Lombok 在 Java 注释处理器中使用 known trick 将代码添加到您的 class。此添加的代码在注释处理器轮次期间对 Parceler 不可见,并且使添加的无参数构造函数对 Parceler 未知。
我建议手动添加无参数构造函数,用 @ParcelConstructor
注释现有构造函数(我假设你有一个)或考虑使用具有 @Parcelable
注释.
我们最近有一个 issue/question 关于这个:https://github.com/johncarl81/parceler/issues/177
在构建空对象的静态方法上使用@ParcelFactory:
@Builder
public class MyClass {
@ParcelFactory
static MyClass fromParcel() {
return builder().build();
}
}
这个技巧可以与 Jackson 和其他库一起使用,允许您在构造函数之外注释静态工厂方法。
编辑: 在我做了一些清理后初始解决方案失败了,而且它不适用于 Proguard。请参阅下面更新的解决方案。
为了解决这个问题,我必须创建自己的自定义注释处理器。该处理器的想法是确保 Lombok 和 Parceler 使用的处理器的处理器顺序。
以下是我解决此问题所遵循的步骤:
步骤 1
在根项目下创建一个新的 Java 模块。任意命名,例如 parceler-lombok
,使用您选择的任何 class name/package。
步骤 2
添加 lombok 和 Parceler 注释 classes 作为对新模块的依赖,并设置源兼容性。
//File: parceler-lombok/build.gradle
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'org.projectlombok:lombok:1.16.16'
compile 'org.parceler:parceler:1.1.9'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
步骤 3
在模块的主源文件夹中创建以下目录:src/main/resources/META-INF/services
步骤 4
在上面的目录中创建一个名为 javax.annotation.processing.Processor
的文件。
步骤 5
编辑文件,添加以下行。
lombok.launch.AnnotationProcessorHider$AnnotationProcessor
lombok.launch.AnnotationProcessorHider$ClaimingProcessor
org.parceler.ParcelAnnotationProcessor
这是您的模块中所有可用注释处理器的声明。该顺序表明 Lombok 注释处理器应该在 parceler 的
之前加载步骤 6
现在我们有了 "custom annotation processor",回到您的主应用程序模块,在应用程序的 build.gradle 文件中,执行以下操作:
- 移除lombok依赖(annotatorProcessor,提供或编译)指令
- 删除 parceler annotationProcessor 依赖项(即
org.parceler:parceler
),保持 API 依赖项不变。 - 现在将您的自定义注释处理器添加为依赖项
- 最后,确保 Java 1.7 兼容性
请参阅以下片段:
//File: app/build.gradle
android {
//...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
//...
}
dependencies {
// ...
//Remove these ones
//provided 'org.projectlombok:lombok:1.16.16'
//annotationProcessor 'org.parceler:parceler:1.1.9'
//leave parceler API
compile 'org.parceler:parceler-api:1.1.9'
provided project(':parceler-lombok')
}
使用 provided 可确保注解处理器 class 不会与您的应用捆绑在一起。
以下文章很有帮助: