Comment ajouter un objet Enum à un bundle Android?
Comment ajouter un objet Enum à un bundle Android?
Réponses:
Les énumérations sont sérialisables, il n'y a donc aucun problème.
Étant donné l'énumération suivante:
enum YourEnum {
TYPE1,
TYPE2
}
Paquet:
// put
bundle.putSerializable("key", YourEnum.TYPE1);
// get
YourEnum yourenum = (YourEnum) bundle.get("key");
Intention:
// put
intent.putExtra("key", yourEnum);
// get
yourEnum = (YourEnum) intent.getSerializableExtra("key");
outState.putSerializable("trollData", game.getFunkyTrolls());
chargement game.setFunkyTrolls((Game.FunkyTroll[]) savedInstanceState.getSerializable("trollData"));
:?
ClassNotFoundException
Je sais que c'est une vieille question, mais je suis venu avec le même problème et je voudrais partager comment je l'ai résolu. La clé est ce que Miguel a dit: les énumérations sont sérialisables.
Étant donné l'énumération suivante:
enum YourEnumType {
ENUM_KEY_1,
ENUM_KEY_2
}
Mettre:
Bundle args = new Bundle();
args.putSerializable("arg", YourEnumType.ENUM_KEY_1);
Par souci d'exhaustivité, ceci est un exemple complet de la façon de mettre en place et de récupérer une énumération à partir d'un bundle.
Étant donné l'énumération suivante:
enum EnumType{
ENUM_VALUE_1,
ENUM_VALUE_2
}
Vous pouvez mettre l'énumération dans un bundle:
bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1);
Et récupérez l'énumération:
EnumType enumType = (EnumType)bundle.getSerializable("enum_key");
J'utilise du kotlin.
companion object {
enum class Mode {
MODE_REFERENCE,
MODE_DOWNLOAD
}
}
puis mettre en intention:
intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name)
lorsque vous net pour obtenir de la valeur:
mode = Mode.valueOf(intent.getStringExtra(KEY_MODE))
.name
est un chemin très important
.name
in putString()
. Avec Kotlin, c'est déjà simplifié si vous l'utilisez .apply
. Par exemple :ContentFragment.newInstance(Bundle().apply { putString(FEED_TYPE_KEY, SAVED.name) })
bundle.putEnum(key, enum) | bundle.getEnum<>(key)
Il peut être préférable de le passer en tant que chaîne à partir de myEnumValue.name () et de le restaurer à partir de YourEnums.valueOf (s), sinon la commande de l'énumération doit être préservée!
Explication plus longue: conversion de l'énumération ordinale en type énumération
Une autre option:
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());
}
}
putSerializable(key, value)
/ (Type) getSerializable(key)
ou putString(key, value.name())
/ Type.valueOf(getString(key))
, la mise en œuvre de Parcelable est ici redondante et absurde.
Parcelable
est une bonne solution pour stocker des tableaux de valeurs Enum.
Utilisez bundle.putSerializable (clé de chaîne, Serializable s) et bundle.getSerializable (clé de chaîne):
enum Mode = {
BASIC, ADVANCED
}
Mode m = Mode.BASIC;
bundle.putSerializable("mode", m);
...
Mode m;
m = bundle.getSerializable("mode");
Documentation: http://developer.android.com/reference/android/os/Bundle.html
Pour l' intention, vous pouvez utiliser cette méthode:
Intention: kotlin
FirstActivity:
val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("type", typeEnum.A)
startActivity(intent)
SecondActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
val type = (intent.extras?.get("type") as? typeEnum.Type?)
}
Une chose à savoir - si vous utilisez bundle.putSerializable
pour Bundle
ajouter un à une notification, vous pouvez rencontrer le problème suivant:
*** Uncaught remote exception! (Exceptions are not yet supported across processes.)
java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object.
...
Pour contourner ce problème, vous pouvez procéder comme suit:
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);
}
}
}
Qui peut ensuite être utilisé comme ceci:
// Put
Bundle bundle = new Bundle();
bundle.putInt("key", MyEnum.TYPE_0.getCode());
// Get
MyEnum myEnum = MyEnum.fromCode(bundle.getInt("key"));
Une manière simple, attribuer une valeur entière à enum
Voir l'exemple suivant:
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;
}
}
Côté expéditeur:
Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class);
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue());
startActivity(nextIntent);
Côté récepteur:
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();
Je pense que convertir l'énumération en int (pour l'énumération normale), puis définir le bundle a été la manière la plus simple. comme ce code d'intention:
myIntent.PutExtra("Side", (int)PageType.Fornt);
puis pour vérifier l'état:
int type = Intent.GetIntExtra("Side",-1);
if(type == (int)PageType.Fornt)
{
//To Do
}
mais ne fonctionne pas pour tous les types d'énumération!
J'ai créé une extension Koltin:
fun Bundle.putEnum(key: String, enum: Enum<*>) {
this.putString( key , enum.name )
}
inline fun <reified T: Enum<T>> Intent.getEnumExtra(key:String) : T {
return enumValueOf( getStringExtra(key) )
}
Créez un bundle et ajoutez:
Bundle().also {
it.putEnum( "KEY" , ENUM_CLAS.ITEM )
}
et obtenir:
intent?.getEnumExtra< ENUM_CLAS >( "KEY" )?.let{}