Android HashMap dans le bundle?

90

Le android.os.Messageutilise a Bundlepour envoyer avec sa méthode sendMessage. Par conséquent, est-il possible de mettre un à l' HashMapintérieur d'un Bundle?

Marcus Toepper
la source
java ET newbie android 8) merci à tous!
Marcus Toepper
Acceptez toute réponse si nous avons résolu votre problème. thx
AMerle

Réponses:

164

essayez comme:

Bundle extras = new Bundle();
extras.putSerializable("HashMap",hashMap);
intent.putExtras(extras);

et en deuxième activité

Bundle bundle = this.getIntent().getExtras();

if(bundle != null) {
   hashMap = bundle.getSerializable("HashMap");
}

parce que Hashmap implémente par défaut Serializableafin que vous puissiez le transmettre en utilisant putSerializabledans Bundle et entrer dans une autre activité en utilisantgetSerializable

ρяσѕρєя K
la source
Je reçois une erreur lorsque je tente de sérialiser le colis de carte de hachage lié: impossible de marshaler la valeur com.SGID.DataClass.InvalidSubscriptionReasonsData@41bd2b98
SweetWisher isher
1
Puis-je utiliser cette méthode pour un objet contenant un type de données primitif et une liste de tableaux d'un autre objet?
SweetWisher ツ
3
Si vous rencontrez des problèmes, assurez-vous que vous utilisez HashMap et non Map
Matthieu
1
vous pouvez convertir l'objet sérialisable renvoyé en hashmap de la manière suivante (HashMap <String, Integer>)
cammando
3
Cela produit un avertissement concernant la distribution non contrôlée. Est-ce sûr d'ignorer?
mitsest
12

Selon la doc , Hashmapimplémente Serializable, donc vous pouvez putSerializableje suppose. Est-ce que tu l'as essayé ?

AMerle
la source
6

Remarque: si vous utilisez une AppCompatActivity, vous devrez appeler la méthode protected void onSaveInstanceState(Bundle outState) {}( NOT public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {} ).

Exemple de code ...

Stockez la carte:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("leftMaxima", leftMaxima);
    outState.putSerializable("rightMaxima", rightMaxima);
}

Et recevez-le dans onCreate:

if (savedInstanceState != null) {
    leftMaxima = (HashMap<Long, Float>) savedInstanceState.getSerializable("leftMaxima");
    rightMaxima = (HashMap<Long, Float>) savedInstanceState.getSerializable("rightMaxima");
}

Désolé si c'est une sorte de réponse en double - peut-être que quelqu'un la trouvera utile. :)

Martin Pfeffer
la source
4

Si vous souhaitez envoyer toutes les clés du bundle, vous pouvez essayer

for(String key: map.keySet()){
    bundle.putStringExtra(key, map.get(key));
}
Cuves Kapil
la source
Je suis curieux de savoir s'il y a une raison de ne pas faire ça? Je n'ai pas beaucoup utilisé la sérialisation, et jamais de bundles (nouveau sur Android), donc je suis curieux de savoir si c'est O (n) et l'ajout à un bundle est effectivement O (1) ou non. S'ils ne sont pas différents en termes de coût, ne voyez pas pourquoi vous vous embêteriez à le sérialiser dans une autre carte.
Captain Prinny
@CaptainPrinny à moins que la carte ne soit la seule chose que vous mappez sur le bundle, vous pourriez écraser des valeurs et vous ne saurez pas si une clé faisait partie de la carte d'origine ou simplement une valeur stockée dans le bundle.
Jason le
1
  public static Bundle mapToBundle(Map<String, Object> data) throws Exception {
    Bundle bundle = new Bundle();
    for (Map.Entry<String, Object> entry : data.entrySet()) {
        if (entry.getValue() instanceof String)
            bundle.putString(entry.getKey(), (String) entry.getValue());
        else if (entry.getValue() instanceof Double) {
            bundle.putDouble(entry.getKey(), ((Double) entry.getValue()));
        } else if (entry.getValue() instanceof Integer) {
            bundle.putInt(entry.getKey(), (Integer) entry.getValue());
        } else if (entry.getValue() instanceof Float) {
            bundle.putFloat(entry.getKey(), ((Float) entry.getValue()));
        }
    }
    return bundle;
}
Jasss
la source
1

J'utilise mon implémentation kotlin de Parcelable pour y parvenir et jusqu'à présent, cela fonctionne pour moi. C'est utile si vous voulez éviter le sérialisable lourd.

Aussi pour que cela fonctionne, je recommande de l'utiliser avec ces

Déclaration

class ParcelableMap<K,V>(val map: MutableMap<K,V>) : Parcelable {
    constructor(parcel: Parcel) : this(parcel.readMap(LinkedHashMap<K,V>()))

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeMap(map)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<ParcelableMap<Any?,Any?>> {
        @JvmStatic
        override fun createFromParcel(parcel: Parcel): ParcelableMap<Any?,Any?> {
            return ParcelableMap(parcel)
        }
        @JvmStatic 
        override fun newArray(size: Int): Array<ParcelableMap<Any?,Any?>?> {
            return arrayOfNulls(size)
        }
    }

}

Utilisation

écrire

val map = LinkedHashMap<Int, String>()
val wrap = ParcelableMap<Int,String>(map)
Bundle().putParcelable("your_key", wrap)

lis

val bundle = fragment.arguments ?: Bundle()
val wrap = bundle.getParcelable<ParcelableMap<Int,String>>("your_key")
val map = wrap.map

N'oubliez pas que si votre carte K,Vn'est pas parcellisée par défaut, elle doit implémenterParcelable

Jocky Doe
la source
1
Avez-vous essayé de raccourcir avec @Parcelize?
CoolMind
0

À Kotlin:

hashMap = savedInstanceState?.getSerializable(ARG_HASH_MAP) as? HashMap<Int, ValueClass>

putSerializable(ARG_HASH_MAP, hashMap)
CoolMind
la source