【问题标题】:Use Android Annotations with Parceler将 Android 注解与 Parceler 一起使用
【发布时间】:2016-04-21 23:22:21
【问题描述】:

我在我的 Android 项目中使用 Android 注释。由于实现 Parcelable 需要做很多工作,我想使用 Parceler 和 @Parcel 注释。

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

  • Parceler 将生成的类放在哪里以便我可以使用这些类? parceler.org 上声明:“要使用生成的代码,您可以直接引用生成的类,或通过 Parcels 实用程序类”
  • 还有其他方法可以使用 Parceler 或任何使用 Android Annotations 生成 Parcelable 样板代码的库吗?

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

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

生成的POJO类用@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;
}
// ...

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

【问题讨论】:

    标签: android parcelable android-annotations parceler


    【解决方案1】:

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

    这就是我的意思:

    @EFragment(R.layout.fragment_faq)
    public class FaqFragment extends ListFragment {
        @FragmentArg
        Parcelable faqParcelable;
    
        public void useFaq(){
            List<FaqItemImpl> faqItems = Parcels.unwrap(faqParcelable);
            // ...
        }
    }
    

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

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

    是的,这种方法不如 AA 为您发出 wrap/unwrap 调用那么好,但它应该可以工作。

    编辑

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

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

    【讨论】:

    • 感谢您的回答。它以这种方式工作。但是,在使用活动尝试此操作时,我得到了一个异常:org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for FaqItemImpl.
    • 听起来 Parceler 没有生成必要的 Parcelable。检查 Parceler 是否配置正确并且正在生成代码。
    • 问题已解决,与此问题无关。再次感谢。
    • @johncarl 很好,我不知道Parcels 能够将List&lt;Object&gt; 包装成一个Parcelable
    • 谢谢@WonderCsabo。这提醒了我,我需要将此添加到文档中。
    【解决方案2】:

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

    @FragmentArg
    ArrayList<FaqItemImpl.Parcelable> faqItems;
    

    其实有一个attemptparceler整合到AndroidAnnotations中,但由于某些原因被拒绝了。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-06
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 2013-11-06
      • 2015-02-21
      • 2015-10-24
      • 1970-01-01
      相关资源
      最近更新 更多