2010-07-20 12 views
224

¿Cómo se agrega un objeto Enum a un paquete de Android?Android: ¿Cómo poner un Enum en un paquete?

+8

En mi opinión de que el asesoramiento de personal de Google es malo. Los enum son muy convenientes y sufren la sobrecarga descrita. – ognian

+2

puede revisar las respuestas y aceptar la segunda si cree que podría ser una mejor opción. – philipp

+5

Bajo el título "Cómo evitar enumeraciones" en el enlace de arriba ahora dice esto: Rendimiento Mitos Las versiones anteriores de este documento hacen varias afirmaciones engañosas. Nos dirigimos a algunos de ellos aquí. – StackOverflowed

Respuesta

-21

Solo pásalo como int de ordinal(). Restaurelo de los valores [].

+75

Esto NO se recomienda en absoluto. El problema es uno de mantenibilidad. Un Intento tiene el potencial de provenir de otras fuentes o de originarse en código que lee datos que son más antiguos que la versión del código que restaura la enumeración del Bundle. Por lo tanto, el ordinal guardado puede no corresponderse con el índice del valor enum correcto. La solución recomendada es el uno por @miguel: simplemente almacenar la enumeración directa y restaurarlo llamando Intención # getSerializableExtra (String) y echó de nuevo al tipo de enumeración. – Warlax

+1

plain old bad ver http: // stackoverflow.com/a/5309967/261363 – Calin

+1

Marque la respuesta de @miguel como la correcta. Gracias. –

15

Puede ser mejor pasarlo como una cadena de myEnumValue.name() y restaurarlo desde YourEnums.valueOf (s), ya que de lo contrario se debe conservar el orden de la enumeración.

explicación más larga: Convert from enum ordinal to enum type

+0

El orden no importa si la serialización-> deserialización ocurre inmediatamente en el tiempo de ejecución, como al llamar de una actividad a otra. Podría ser un problema en procesos como el envío de Intenciones desde una aplicación a versiones anteriores de la aplicación. – miguel

513

enumeraciones son Serializable lo que no hay problema.

Dada la siguiente enumeración:

enum YourEnum { 
    TYPE1, 
    TYPE2 
} 

Bundle:

// put 
bundle.putSerializable("key", YourEnum.TYPE1); 

// get 
YourEnum yourenum = (YourEnum) bundle.get("key"); 

Intención:

// put 
intent.putExtra("key", yourEnum); 

// get 
yourEnum = (YourEnum) intent.getSerializableExtra("key"); 
+0

¿Hay algún problema con este método? guardando: 'outState.putSerializable (" trollData ", game.getFunkyTrolls());' cargando: 'game.setFunkyTrolls ((Game.FunkyTroll []) savedInstanceState.getSerializable (" trollData ")); '? – Moberg

+19

Hubiera votado su respuesta, pero la pregunta fue sobre agregar Enum a un paquete y su respuesta explica cómo agregarlo a un intento ... De acuerdo, es casi lo mismo, pero Alejandro a continuación ha resuelto su respuesta. – Pooks

+1

cuando se utiliza con Bundle, arroja 'ClassNotFoundException' –

145

Sé que esto es una vieja pregunta, pero me encontré con el mismo problema y Me gustaría compartir cómo lo resolví. La clave es lo que Miguel dijo: los mensajes son serializables.

Dada la siguiente enumeración:

enum YourEnumType { 
    ENUM_KEY_1, 
    ENUM_KEY_2 
} 

Put:

Bundle args = new Bundle(); 
args.putSerializable("arg", YourEnumType.ENUM_KEY_1); 
+9

esta debería ser la respuesta aceptada ... – Mars

+3

Basado en esto: http: //stackoverflow.com/questions/15521309/is-custom-enum-serializable-too, los Enums personalizados no son serializables. Entonces los campos personalizados en un Enum no serán serializados. Como tratas con esto? – clu

+0

Buena pregunta @clu! Tal vez entonces deberías pensar en pasarlo como una cadena como se indica en http://stackoverflow.com/questions/609860/convert-from-enum-ordinal-to-enum-type/609879#609879 –

32

Para completarlo, esto es un ejemplo completo de cómo poner en y volver una enumeración de un paquete.

Dada la siguiente enumeración:

enum EnumType{ 
    ENUM_VALUE_1, 
    ENUM_VALUE_2 
} 

Usted puede poner la enumeración en un paquete:

bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1); 

y conseguir la enumeración de vuelta:

EnumType enumType = (EnumType)bundle.getSerializable("enum_key"); 
4

Otra opción:

public enum DataType implements Parcleable { 
SIMPLE, COMPLEX; 

public static final Parcelable.Creator<DataType> CREATOR = new Creator<DataType>() { 

    @Override 
    public DataType[] newArray(int size) { 
     return new DataType[size]; 
    } 

    @Override 
    public DataType createFromParcel(Parcel source) { 
     return DataType.values()[source.readInt()]; 
    } 
}; 

@Override 
public int describeContents() { 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeInt(this.ordinal()); 
} 

}

+0

Puede usar 'putSerializable (clave, valor)'/'(Tipo) getSerializable (clave)' o 'putString (clave, valor.nombre())' /'Type.valueOf (getString (clave)) ', Parcelable la implementación aquí es redundante y sin sentido. –

0

Una manera simple, asignar valor entero es posible enumerar los

Véase el siguiente ejemplo:

public enum MyEnum { 

    TYPE_ONE(1), TYPE_TWO(2), TYPE_THREE(3); 

    private int value; 

    MyEnum(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return value; 
    } 

} 

remitente lateral:

Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class); 
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue()); 
startActivity(nextIntent); 

receptor lateral:

Bundle mExtras = getIntent().getExtras(); 
int mType = 0; 
if (mExtras != null) { 
    mType = mExtras.getInt("key_type", 0); 
} 

/* OR 
    Intent mIntent = getIntent(); 
    int mType = mIntent.getIntExtra("key_type", 0); 
*/ 

if(mType == MyEnum.TYPE_ONE.getValue()) 
    Toast.makeText(NextActivity.this, "TypeOne", Toast.LENGTH_SHORT).show(); 
else if(mType == MyEnum.TYPE_TWO.getValue()) 
    Toast.makeText(NextActivity.this, "TypeTwo", Toast.LENGTH_SHORT).show(); 
else if(mType == MyEnum.TYPE_THREE.getValue()) 
    Toast.makeText(NextActivity.this, "TypeThree", Toast.LENGTH_SHORT).show(); 
else 
    Toast.makeText(NextActivity.this, "Wrong Key", Toast.LENGTH_SHORT).show(); 
+0

La forma más hinchada y propensa a errores. –

0

creo convertir enum a int (por enumeración normal) y luego fue puesto en bulto sido manera más fácil. al igual que el código de la intención:

myIntent.PutExtra("Side", (int)PageType.Fornt); 

luego por estado de comprobación:

int type = Intent.GetIntExtra("Side",-1); 
if(type == (int)PageType.Fornt) 
{ 
    //To Do 
} 

pero no funciona para todo tipo de enumeración!

10

utilizo Kotlin.

companion object { 

     private enum class Mode { 
      MODE_REFERENCE, 
      MODE_DOWNLOAD 
     } 
} 

después puesto en Intención:

intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name) 

cuando red para obtener valor:

mode = Mode.valueOf(intent.getStringExtra(KEY_MODE)) 
1

Una cosa a tener en cuenta - si está utilizando bundle.putSerializable para un Bundle a se añade a una notificación, usted podría encontrarse con el problema siguiente:

*** Uncaught remote exception! (Exceptions are not yet supported across processes.) 
    java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object. 

... 

Para evitar esto, puede hacer lo siguiente:

public enum MyEnum { 
    TYPE_0(0), 
    TYPE_1(1), 
    TYPE_2(2); 

    private final int code; 

    private MyEnum(int code) { 
     this.code = navigationOptionLabelResId; 
    } 

    public int getCode() { 
     return code; 
    } 

    public static MyEnum fromCode(int code) { 
     switch(code) { 
      case 0: 
       return TYPE_0; 
      case 1: 
       return TYPE_1; 
      case 2: 
       return TYPE_2; 
      default: 
       throw new RuntimeException(
        "Illegal TYPE_0: " + code); 
     } 
    } 
} 

que luego puede ser utilizado de esta manera:

// Put 
Bundle bundle = new Bundle(); 
bundle.putInt("key", MyEnum.TYPE_0.getCode()); 

// Get 
MyEnum myEnum = MyEnum.fromCode(bundle.getInt("key")); 
Cuestiones relacionadas