捆绑中的Android HashMap?


90

android.os.Message使用了Bundle与它的sendMessage法派。因此,可以将HashMap内部放置Bundle吗?


Java和Android新手8)向所有人致敬!
Marcus Toepper

如果我们解决了您的问题,请接受任何答案。thx
AMerle


Answers:


164

尝试为:

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

在第二个活动中

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

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

因为Hashmap 是默认实现的,Serializable所以您可以putSerializable在Bundle中使用它进行传递,并使用getSerializable


尝试序列化链接的哈希映射宗地时出现错误:无法封

1
我可以对包含原始数据类型和另一个对象的数组列表的对象使用此方法吗?
SweetWisher 2013年

3
如果您遇到问题,请确保您使用的是HashMap,而不是Map
Matthew

1
您可能想通过以下方式(HashMap <String,Integer>)将返回的可序列化对象转换为哈希映射
cammando

3
这会产生有关未经检查的演员表的警告。这是可以忽略的安全吗?
mitsest

12

根据文档Hashmap实现Serializable,所以我可以putSerializable猜测。你试过了吗?


6

请注意:如果使用的是AppCompatActivity,则必须调用 protected void onSaveInstanceState(Bundle outState) {}NOT public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {})方法。

示例代码...

储存地图:

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

并在onCreate中接收它:

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

抱歉,如果答案重复,也许有人会觉得有用。:)


4

如果要发送捆绑包中的所有密钥,可以尝试

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

我很好奇是否有任何理由不这样做?我没有太多使用序列化,也从来没有捆绑(对于Android来说是新的),所以我很好奇这是否为O(n)并附加到捆绑中实际上是否为O(1)。如果它们的成本没有差别,那就不明白为什么要麻烦将其序列化到另一个地图中。
普林尼上尉

@CaptainPrinny除非映射是您要映射到捆绑软件的唯一对象,否则您可能会破坏值,并且您将不知道键是原始映射的一部分还是只是存储在捆绑软件中的值。
杰森

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

我正在使用我的Parcelable的kotlin实现来实现这一目标,到目前为止,它对我来说仍然有效。如果要避免大量的可序列化,这将很有用。

另外,为了为它工作,我建议使用它与这些

宣言

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

}

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

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

不要忘记,如果K,V默认情况下未对地图进行包裹,则必须实现Parcelable


1
您是否尝试使用@Parcelize缩短时间?
CoolMind

0

在科特林:

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

putSerializable(ARG_HASH_MAP, hashMap)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.