一般我们在Activity之间传递对象时多用Parcelable。比如写一个class,在这个class上标明implements Parcelable并实现接口就可以用Intent.putExtra(String, Parcelable)了。对于传递enum对象,假设也采用此方法,即像http://stackoverflow.com/questions/2836256/passing-enum-or-object-through-an-intent-the-best-solution里面3楼说的:

  1. public enum MyEnum implements Parcelable {
  2. VALUE;
  3. @Override
  4. public int describeContents() {
  5. return 0;
  6. }
  7. @Override
  8. public void writeToParcel(final Parcel dest, final int flags) {
  9. dest.writeInt(ordinal());
  10. }
  11. public static final Creator<MyEnum> CREATOR = new Creator<MyEnum>() {
  12. @Override
  13. public MyEnum createFromParcel(final Parcel source) {
  14. return MyEnum.values()[source.readInt()];
  15. }
  16. @Override
  17. public MyEnum[] newArray(final int size) {
  18. return new MyEnum[size];
  19. }
  20. };
  21. }
  22. You can than use Intent.putExtra(String, Parcelable).

那么我们先定义一个MyEnum变量a,再调用intent.putExtra("name", a),会报The method putExtra(String, Parcelable) is ambiguous for the type Intent的错,为何?

因为enum自身实现了Serializable接口,Enum类的源代码里这么写的:

  1. public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E> {
  2. ... ...
  3. }

之后你的MyEnum类再实现Parcelable接口,而intent里面有这样两个函数:Intent.putExtra(String, Parcelable)和Intent.putExtra(String, Serializable),你的MyEnum类实现了Serializable和Parcelable两个接口,在调用Intent.putExtra时,编译器就不知道该选Intent.putExtra(String, Parcelable)还是Intent.putExtra(String, Serializable),导致二义性。那么上面的说法是否真的无用?  其实这种写法在MyEnum对象作为类Father1的成员时还是可以这么写的,我们在Activity间传Father1,Father1是可以实现Parcelable接口的。Father1内部处理MyEnum成员时可以这样:

  1. private Father1(Parcel in) {
  2. mField = in.readInt();
  3. mMyEnum = MyEnum.CREATOR.createFromParcel(in);
  4. }
  5. public void writeToParcel(Parcel dest, int flags) {
  6. dest.writeInt(mField);
  7. mMyEnum.writeToParcel(dest, flags);
  8. }

经测试,也可以把enum传递出去。

既然上述MyEnum的写法可以适应enum作为Parcelable类成员来传递,而不能作为单独的对象来传递,要兼得二者该如何做?

首先,MyEnum不需实现Parcelable接口,单独传递MyEnum对象时就用Intent.putExtra(String, Serializable)。

然后把MyEnum的createFromParcel()和writeToParcel()的代码整合进Father类,代码片段(变量名有改动):

  1. private Father2(Parcel in) {
  2. mField = in.readInt();
  3. mAnotherEnum = AnotherEnum.values()[in.readInt()];
  4. }
  5. public static final Parcelable.Creator<Father2> CREATOR = new Parcelable.Creator<Father2>() {
  6. public Father2 createFromParcel(Parcel in) {
  7. return new Father2(in);
  8. }
  9. @Override
  10. public Father2[] newArray(int size) {
  11. return new Father2[size];
  12. }
  13. };
  14. @Override
  15. public void writeToParcel(Parcel dest, int flags) {
  16. dest.writeInt(mField);
  17. dest.writeInt(mAnotherEnum.ordinal());
  18. }

再用Intent.putExtra(String, Parcelable)来传Father2对象就可以了。

再谈一下Enum类的values()方法,这个方法是无法通过eclipse查看到的,它的定义在这里,它返回所有的定义过的枚举值,enum的底层实现就是定义从0到N的数个整数,只不过为每个整数取了个别名,一个enum变量就是这数个整数之一,这个enum变量的ordinal()方法就是返回其在这数个整数中的位置。values()静态方法返回一个包含这数个整数的数组。

给出示例代码(免积分下载),在MainActivity.java三处注释的地方,分别解注释再运行,就会认识得比较清楚了。

enum类型被intent所携带时需要注意的地方的更多相关文章

  1. 【转】Intent传递数据时,可以传递哪些类型数据?

    在Android应用的开发中,如果我们需要在不同的模块(比如不同的Activity之间)之间传递数据,通常有以下两种方法:1. 利用Intent对象携带数据通过查询Intent/Bundle的API文 ...

  2. set和enum类型的用法和区别

    mysql中的set和enum类型的用法和区别 mysql中的enum和set其实都是string类型的而且只能在指定的集合里取值, 不同的是set可以取多个值,enum只能取一个值.   1 2 3 ...

  3. MYSQL中 ENUM 类型

    MYSQL中 ENUM 类型的详细解释 ENUM类型 ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串(&quo ...

  4. enum类型的本质(转)

    原地址:http://www.cppblog.com/chemz/archive/2007/06/05/25578.html 至从C语言开始enum类型就被作为用户自定义分类有限集合常量的方法被引入到 ...

  5. mysql中enum类型

    ENUM类型 ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串("") 或 NULL: 如果 ...

  6. EffectiveJava(30) -- 全面解析enum类型

    --在大多数项目中,我们会经常使用int类型来声明final类型的常量,它在不考虑安全的情况下确实能满足我们绝大多数的需求.但是在JDK1.5版本发布之后,声明一组固定的常量组成合法值的类型就建议使用 ...

  7. Enum 类型

    枚举类型(Enumerated Type) 什么是枚举? 枚举是一个被命名的整型常数的集合.在多种编程语言中都有使用(C/C++/c#/java等). 示例 public enum Size { S, ...

  8. C#中enum类型

    最近碰到了枚举类型,就顺便整理下. 枚举的基类Enum,可以是除 Char 外的任何整型.不做显示声明的话,默认是整形(Int32). 声明一个Enum类型: /// <summary> ...

  9. C#遍历enum类型

    对于enum类型: 使用foreach遍历enum类型的元素并填充combox foreach ( HatchStyle hs1 in Enum.GetValues(typeof(HatchStyle ...

随机推荐

  1. Android中用Application类实现全局变量

    最近在项目中,遇到了application这个类,开始不知道有什么用,经过学习后才知道它的用途也蛮大的,举个例子,如果想在整个应用中使用全局变量,在java中一般是使用静态变量,public类型:而在 ...

  2. jQuery 插件写法

    一.jQuery插件的类型 1. jQuery方法 很大一部分的jQuery插件都是这种类型,由于此类插件是将对象方法封装起来,在jQuery选择器获取jQuery对象过程中进行操作,从而发挥jQue ...

  3. 【python】只执行普通除法:添加 from __future__ import division

    from __future__ import division 注意future前后是两个下划线

  4. Centos7 修改运行级别

    systemd使用比sysvinit的运行级别更为自由的target概念作为替代 第三运行级: multi-user.target 第五运行级: graphical.target   #前者是符号链接 ...

  5. 安装Java

    1.在Oracle的官网下载需要的jdk,这里选择JDK1.8,下面,是下载的网址 http://www.oracle.com/technetwork/java/javase/downloads/jd ...

  6. http server v0.1_http_webapp.c

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h&g ...

  7. 解决maven打jar包报错 source 1.3 中不支持

    问题:maven在进行打包时,报 '请使用-source 5 或者更高版本以启用XX'的信息并导致打包失败. 原因:maven默认的编译插件的java版本较低,导致其不支持例如泛型,注解等用法. 解决 ...

  8. Eclipse中Android公共库的正确建立及调用方法

    Eclipse中Android公共库的正确建立及调用方法 引言 之前一直头痛于没有办法在多个程序中共享资源,用作公共类库的方法也是使用的导出jar再导入的办法,现在终于初步搞明白了,可算解脱了~,分享 ...

  9. IndexedDB

    http://www.tfan.org/indexeddb/ http://fnvfox.appspot.com/thankyou.html http://www.tfan.org/wechat-on ...

  10. DUILIB创建不规则窗体,自定义控件(很不错的几十篇文章)

    http://blog.csdn.net/harvic880925/article/details/8925650 http://blog.csdn.net/harvic880925/article/ ...