HashMap Android in bundle?


90

Il android.os.Messageutilizza una Bundledi inviare con il suo sendMessage-metodo. Quindi è possibile inserire un HashMapall'interno di un Bundle?


java AND android newbie 8) grazie a tutti!
Marcus Toepper

Accetta qualsiasi risposta se abbiamo risolto il tuo problema. thx
AMerle


Risposte:


164

prova come:

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

e nella seconda attività

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

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

perché Hashmap per impostazione predefinita implementa in Serializablemodo da poterlo passare utilizzando putSerializablein Bundle e ottenere altre attività utilizzandogetSerializable


Ricevo un errore quando provo a serializzare la mappa hash collegata Parcel: impossibile eseguire il marshalling del valore com.SGID.DataClass.InvalidSubscriptionReasonsData@41bd2b98
SweetWisher ツ

1
Posso usare questo metodo per oggetti che contengono un tipo di dati primitivo e un elenco di array di un altro oggetto?
SweetWisher ツ

3
In caso di problemi, assicurati di utilizzare HashMap e non Map
Matthew

1
potresti voler eseguire il cast dell'oggetto serializzabile restituito su hashmap seguendo i modi (HashMap <String, Integer>)
cammando

3
Questo produce un avviso sul cast non controllato. È sicuro ignorarlo?
mitsest

12

Secondo il documento , Hashmapimplementa Serializable, quindi putSerializableimmagino. Hai provato ?


6

Nota: se stai usando AppCompatActivity, dovrai chiamare il metodo protected void onSaveInstanceState(Bundle outState) {}( NOT public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {} ).

Codice di esempio ...

Memorizza la mappa:

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

E riceverlo in onCreate:

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

Scusa se è una sorta di risposta duplicata, forse qualcuno la troverà utile. :)


4

Se vuoi inviare tutte le chiavi del pacchetto, puoi provare

for(String key: map.keySet()){
    bundle.putStringExtra(key, map.get(key));
}

Sono curioso se c'è qualche motivo per non farlo? Non ho usato molto la serializzazione e mai i bundle (nuovi per Android), quindi sono curioso di sapere se questo è O (n) e l'aggiunta a un bundle è effettivamente O (1) o meno. Se non sono diversi nel costo, non vedo perché ti preoccupi di serializzarlo in un'altra mappa.
Capitano Prinny

@CaptainPrinny a meno che la mappa non sia l'unica cosa che stai mappando al bundle, potresti sovrascrivere i valori e non saprai se una chiave faceva parte della mappa originale o solo un valore memorizzato nel bundle.
Jason

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;
}

1

Sto usando la mia implementazione kotlin di Parcelable per raggiungere questo obiettivo e finora funziona per me. È utile se vuoi evitare il serializzabile pesante.

Inoltre, affinché funzioni, consiglio di usarlo con questi

Dichiarazione

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)
        }
    }

}

Uso

Scrivi

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

leggere

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

Non dimenticare che se la tua mappa K,Vnon è parcellizzata per impostazione predefinita, devono essere implementateParcelable


1
Hai provato ad accorciare con @Parcelize?
CoolMind

0

A Kotlin:

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

putSerializable(ARG_HASH_MAP, hashMap)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.