Android HashMap w pakiecie?

91

android.os.MessageUżywa Bundledo wysyłania z jego sendMessage sposobem. Dlatego czy można umieścić HashMapwewnątrz Bundle?

Marcus Toepper
źródło
java i android newbie 8) dziękuję wszystkim!
Marcus Toepper,
Zaakceptuj dowolną odpowiedź, jeśli rozwiązaliśmy Twój problem. thx
AMerle

Odpowiedzi:

165

spróbuj jako:

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

iw drugim ćwiczeniu

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

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

ponieważ Hashmap domyślnie implementuje, Serializablewięc możesz przekazać go używając putSerializablew pakiecie i uzyskać w innej aktywności używającgetSerializable

ρяσѕρєя K
źródło
Otrzymuję błąd podczas próby serializacji połączonej mapy skrótów Parcel: nie można zorganizować wartości com.SGID.DataClass.InvalidSubscriptionReasonsData@41bd2b98
SweetWisher ツ
1
Czy mogę użyć tej metody dla obiektu, który zawiera pierwotny typ danych i listę tablic innego obiektu?
SweetWisher ツ
3
Jeśli masz problemy, upewnij się, że używasz mapy HashMap, a nie mapy
Matthew
1
możesz chcieć rzutować zwrócony obiekt możliwy do serializacji na hashmap, wykonując następujące sposoby (HashMap <String, Integer>)
cammando
3
To generuje ostrzeżenie o niesprawdzonych rzutach. Czy można to zignorować?
mitsest
12

Według doktora , Hashmapnarzędzia Serializable, więc putSerializabledomyślam się. Próbowałeś tego?

AMerle
źródło
6

Uwaga: jeśli używasz AppCompatActivity, będziesz musiał wywołać metodę protected void onSaveInstanceState(Bundle outState) {}( NOT public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {} ).

Przykładowy kod ...

Przechowuj mapę:

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

I otrzymaj to w onCreate:

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

Przepraszam, jeśli to jakaś podwójna odpowiedź - może ktoś uzna ją za przydatną. :)

Martin Pfeffer
źródło
4

Jeśli chcesz wysłać wszystkie klucze w pakiecie, możesz spróbować

for(String key: map.keySet()){
    bundle.putStringExtra(key, map.get(key));
}
Kapil Vats
źródło
Ciekawi mnie, czy jest jakiś powód, żeby tego nie robić? Nie używałem zbyt często serializacji i nigdy nie zawiera pakietów (nowość w Androidzie), więc jestem ciekawy, czy to jest O (n), a dołączanie do pakietu jest w rzeczywistości O (1), czy nie. Jeśli nie różnią się kosztami, nie widząc, dlaczego miałbyś zawracać sobie głowę serializacją na inną mapę.
Kapitan Prinny
@CaptainPrinny, chyba że mapa jest jedyną rzeczą, którą mapujesz do pakietu, możesz przebić wartości i nie będziesz wiedział, czy klucz był częścią oryginalnej mapy, czy tylko wartością przechowywaną w pakiecie.
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
źródło
1

Aby to osiągnąć, używam mojej implementacji kotlin Parcelable i jak dotąd działa dla mnie. Jest to przydatne, jeśli chcesz uniknąć ciężkich serializacji.

Aby to zadziałało, polecam używanie go z nimi

Deklaracja

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

}

Posługiwać się

pisać

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

czytać

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

Nie zapominaj, że jeśli twoja mapa K,Vnie jest domyślnie spakowana, musi to zaimplementowaćParcelable

Jocky Doe
źródło
1
Czy próbowałeś skrócić za pomocą @Parcelize?
CoolMind
0

W Kotlinie:

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

putSerializable(ARG_HASH_MAP, hashMap)
CoolMind
źródło