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 不会与您的应用捆绑在一起。


以下文章很有帮助: