2016-08-04 13 views
2

Ich möchte eine Java-Enumeration als int. Serialisieren/deserialisieren. Ich verwende die Wearable Data Layer-API von Android Wear, um eine Enum-Einstellung zwischen Wear- und Phone-Geräten zu übertragen. Dies bedeutet, dass ich meine enum zu einem int und zurück zu einem enum programmatisch konvertieren muss. Beachten Sie, dass ich KEINE neuen Enums erstellen muss, sondern nur eine bestehende. Meine Sorge ist, dass, obwohl ich leicht einen Wert mit einer Aufzählung Methode setzen kann, es scheint, dass ich einfach einen nicht vorhandenen Wert festlegen konnte.Android Enum: Set enum programmatisch von Integer-Wert

public enum Color { 
    Undefined (0), Red(1), Yellow(2), Blue(3), Green(4), Black(5); 
    private int mValue; 
    private Color(int value) { this.mValue = value;} // Constructor 
    public int id(){return mValue;}     // Return enum index 
    public void setValue(int i){mValue = i;};  // Set index 
} 

So kann ich folgendes tun:

Color color = Color.Red; 
int index = color.id(); 
putDataMapReq.getDataMap().putInt("color",index);   

Dieser Wert kann als int transportiert werden, und ich möchte es zur Rekonstitution wie folgt aber ich kann die setValue nicht get() Zugriffsmethode:

int newindex = dataMap.getInt ("color"); 
Color newColor = Color.Undefined; 
newColor.setValue(newIndex); 

Was ist das der richtige Weg? Gibt es eine Möglichkeit zu validieren, dass der neue Indexwert legitim ist?

Antwort

3

Ich empfehle Ihnen, Emen's Methode name und valueof der Einfachheit halber zu verwenden.

Ihre Color wird so aussehen:

public enum Color { 
    Undefined , Red, Yellow, Blue, Green, Black; 
} 

Serialize:

Color color = Color.Red; 
String name = color.name(); 

Deserialize:

String newName = dataMap.getString("color"); 
Color newColor = Color.valueOf(newName); 

UPDATE

Wenn Sie integer verwenden möchten, wird Ihr Code wie unten sein:

public enum Color { 
    Undefined (0), Red(1), Yellow(2), Blue(3), Green(4), Black(5); 
    private int mValue; 
    Color(int value) { this.mValue = value;} // Constructor 
    public int id(){return mValue;}     // Return enum index 

    public static Color fromId(int value) { 
     for(Color color : values()) { 
      if (color.mValue == value) { 
       return color; 
      } 
     } 
     return Undefined; 
    } 
} 

Serialize:

Color color = Color.Red; 
    int index = color.id(); 

Deserialize:

int newIndex = dataMap.getInt("color"); 
    Color newColor = Color.fromId(newIndex); 
+0

Ist es möglich, eine ganze Zahl zu verwenden, als Zwischenwert anstelle eines Strings. Ich möchte Zeichen für den Transport minimieren. – Hephaestus

+0

OK, ich habe meine Antwort aktualisiert. – nshmura

+0

Süß !!!!! Genau das hatte ich vor. – Hephaestus

1

Zuerst habe ich sehr würde vorschlagen, dass Ihr enums werden unveränderlich gemacht, um ihre Benutzer nicht zu überraschen. Die ursprüngliche Verwendung von enums, wie in Java 1.5 documentation angegeben, besteht darin, Listen von Konstanten zu ersetzen.

Wie zum Übertragen von Daten, die Android-Wearable docs on data syncing vorschlagen, mit einem DataMap wann immer möglich:

Wenn möglich, die DataMap Klasse. Bei diesem Ansatz können Sie mit Datenelementen in Form eines Android-Bundles arbeiten, sodass das System Serialisierung und Deserialisierung für Sie anwendet und Sie Daten mit Schlüssel/Wert-Paaren bearbeiten können.

Während ich keine Erfahrung mit Wearables haben, hat Android seine eigene Serialisierungsmechanismus mit Bundle und Parcelable, und es gibt Projekte wie Parceler, die die Serialisierung-Code für Sie generieren helfen. Sie können Bundles mithilfe von #fromBundle(...) in eine DataMap konvertieren.

Wenn Sie die Parceler-Route verwenden, können Sie sich entweder auf die integrierte enum-Serialisierung verlassen oder beliebigen Code schreiben. Es ist ein häufige Java Muster eine enum Instanz von einem kanonischen Wert zu schaffen, indem sie durch available values für ein Spiel suchen (oder suchen sie in einer vorher berechneten Karte, wenn sehr groß):

public enum Foo { 
    VAL_1("bar"); 
    private final String strval; 
    Foo(final String strval) { this.strval = strval; } 

    public static Foo fromStrval(final String strval) { 
    for (final Foo f : Foo.values()) { 
     if (f.strval.equals(strval)) return f; 
    } 

    return null; 
    } 
} 
+0

Del. Vielen Dank für die Kommentare. Ich verwende die DataMap-API und habe den ursprünglichen Post aktualisiert, um den tatsächlichen Datamap-Code zu enthalten. Ich habe auch überprüft und das DataMap-Paket akzeptiert keine Enums (ich hatte das vorher angenommen, aber jetzt einfach überprüft). Dies war der Grund für die Verwendung des Int. – Hephaestus