Android HashMap im Bundle?

90

Das android.os.Messageverwendet a Bundle, um mit seiner sendMessage-Methode zu senden. Ist es daher möglich, ein HashMapInside a zu setzen Bundle?

Marcus Toepper
quelle
Java und Android Neuling 8) Danke an alle!
Marcus Toepper
Akzeptieren Sie jede Antwort, wenn wir Ihr Problem gelöst haben. thx
AMerle

Antworten:

164

versuchen als:

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

und in der zweiten Aktivität

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

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

da Hashmap standardmäßig implementiert ist, Serializablesodass Sie es mit putSerializablein Bundle übergeben und mit anderen Aktivitäten ausführen könnengetSerializable

ρяσssρєя K.
quelle
Beim Versuch, die verknüpfte Hash-Map zu serialisieren, wird eine Fehlermeldung angezeigt. Paket: Wert com.SGID.DataClass.InvalidSubscriptionReasonsData@41bd2b98 kann nicht gemarshallt werden
SweetWisher ツ
1
Kann ich diese Methode für Objekte verwenden, die den primitiven Datentyp und die Array-Liste eines anderen Objekts enthalten?
SweetWisher
3
Wenn Sie Probleme haben, stellen Sie sicher, dass Sie HashMap nicht Map
Matthew
1
Möglicherweise möchten Sie das zurückgegebene serialisierbare Objekt auf folgende Weise in
Hashmap umwandeln
3
Dies erzeugt eine Warnung vor ungeprüfter Besetzung. Ist das sicher zu ignorieren?
Mitsest
12

Nach dem doc , Hashmapimplementiert Serializable, so kann man , putSerializabledenke ich. Hast Du es versucht ?

AMerle
quelle
6

Bitte beachten Sie: Wenn Sie eine AppCompatActivity verwenden, müssen Sie die protected void onSaveInstanceState(Bundle outState) {}( NOT public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {} ) -Methode aufrufen .

Beispielcode ...

Speichern Sie die Karte:

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

Und erhalten Sie es in onCreate:

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

Tut mir leid, wenn es sich um eine doppelte Antwort handelt - vielleicht findet es jemand nützlich. :) :)

Martin Pfeffer
quelle
4

Wenn Sie alle Schlüssel im Bundle senden möchten, können Sie es versuchen

for(String key: map.keySet()){
    bundle.putStringExtra(key, map.get(key));
}
Kapil Vats
quelle
Ich bin gespannt, ob es einen Grund gibt, dies nicht zu tun. Ich habe die Serialisierung nicht viel verwendet und nie gebündelt (neu für Android), daher bin ich gespannt, ob dies O (n) ist und das Anhängen an ein Bündel effektiv O (1) ist oder nicht. Wenn sich die Kosten nicht unterscheiden, sehen Sie nicht, warum Sie sich die Mühe machen, sie in eine andere Karte zu serialisieren.
Kapitän Prinny
@CaptainPrinny Wenn die Map nicht das einzige ist, was Sie dem Bundle zuordnen, können Sie Werte blockieren und wissen nicht, ob ein Schlüssel Teil der ursprünglichen Map war oder nur ein im Bundle gespeicherter Wert.
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;
}
Jasss
quelle
1

Ich benutze meine Kotlin-Implementierung von Parcelable, um dies zu erreichen, und bisher funktioniert es für mich. Es ist nützlich, wenn Sie die schwere Serialisierbarkeit vermeiden möchten.

Auch damit es funktioniert, empfehle ich, es mit diesen zu verwenden

Erklärung

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

}

Verwenden

schreiben

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

lesen

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

Vergessen Sie nicht, dass Ihre Karte K,Vimplementiert werden muss , wenn sie nicht standardmäßig parzelliert istParcelable

Jocky Doe
quelle
1
Haben Sie versucht, mit @Parcelize zu verkürzen?
CoolMind
0

In Kotlin:

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

putSerializable(ARG_HASH_MAP, hashMap)
CoolMind
quelle