在 Parceler 中使用 Android 注释

Use Android Annotations with Parceler

我在我的 Android 项目中使用 Android 注释。由于实施 Parcelable 需要大量工作,所以我想使用 Parceler 和 @Parcel 注释。

问题是,如果我想通过 Android 注释使用 @FragmentArg 注释,它不会(出于显而易见的原因)识别 class 将通过实现的 Parcelable 接口生成. 我现在有两个问题:

到目前为止,我的 Fragment 代码如下所示:

@EFragment(R.layout.fragment_faq)
public class FaqFragment extends ListFragment {
    @FragmentArg
    ArrayList<FaqItemImpl> faqItems;
    // ...
}

生成的POJOclass注解@Parcel:

@Parcel
public class FaqItemImpl implements FaqItem {
    protected String iconURL;
    protected String title;
    protected String question;
    protected String answer;

    protected ArrayList<FaqItemImpl> faqChildren;
    // ...
}

在生成的 FaqFragment_ 中,有趣的部分是:

// ...
public FaqFragment_.FragmentBuilder_ faqItems(ArrayList<FaqItemImpl> faqItems) {
        args.putSerializable(FAQ_ITEMS_ARG, faqItems);
        return this;
}
// ...

如您所见,生成的 class 将 POJO 视为可序列化...

不幸的是,您不能将 @Parcelable 对象与 @FragmentArg(或其他 AA 束注入注释)一起使用。由于您使用的 FaqItemImpl 本身并未实现 Parcelable,因此 AA 不知道如何处理它。一个(丑陋的)解决方案是使用生成的 class:

@FragmentArg
ArrayList<FaqItemImpl.Parcelable> faqItems;

其实有一个attempt可以把parceler整合到AndroidAnnotations但是因为一些原因被拒绝了

plans 可以直接将 Parcelable 样板生成器添加到 AA 中,不幸的是它需要更多的初始工作。

您可以使用的一种方法是让 AA 处理 Parcelable 的交接并让 Parceler 执行 serialization/deserialization。 Parceler 的一个不错的特性是它将为您处理集合序列化,因此 AA 应该只处理单个 Parcelable。这将有效地避免对生成代码的任何引用,当然除了 AA 的下划线 class。

我的意思是:

@EFragment(R.layout.fragment_faq)
public class FaqFragment extends ListFragment {
    @FragmentArg
    Parcelable faqParcelable;

    public void useFaq(){
        List<FaqItemImpl> faqItems = Parcels.unwrap(faqParcelable);
        // ...
    }
}

然后当您准备好构建 FaqFragment 时,您只需让 Parceler 包装您的列表:

FaqFragment_.builder()
  .faqParcelable(Parcels.wrap(faqItems))
  .build();

是的,这种方法不如 AA 为您打电话 wrap/unwrap 好,但它应该有效。

编辑:

与 Android 注释团队合作,我们已将 Parceler 支持添加到 @Extra@FragmentArg@SavedInstanceState 注释字段。这意味着 OP 所需的功能已经到位。这应该有效:

@EFragment(R.layout.fragment_faq)
public class FaqFragment extends ListFragment {
    @FragmentArg
    ArrayList<FaqItemImpl> faqItems;
    // ...
}