在Android App中,我将一个Bundle从一个Activity发送到一个片段。
public class Bar implements Parcelable {
private Map<String, String> hash;
private int id;
protected Bar(Parcel in) {
id = in.readInt();
}
public Bar(int id, Map<String,String> map){
this.hash=map;
this.id=id;
}
public static final Creator<Bar> CREATOR = new Creator<Bar>() {
@Override
public Bar createFromParcel(Parcel in) {
return new Bar(in);
}
@Override
public Bar[] newArray(int size) {
return new Bar[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
}
}
我已经使用Android工作室实现了Parcelable inteli sense帮助并自动生成了上面的代码,它没有实现Map。
当我像这样发送给我的片段时:
Map<String,String> map = new HashMap<String, String>();
map.put("foo","bar");
map.put("foobar","barfoo");
Bar foo = new Bar(1,map);
MyFragment fragment = new MyFragment();
Bundle bundle = new Bundle();
fragment.setArguments(bundle);
bundle.putParcelable("foo",foo);
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, fragment, "foo");
fragmentTransaction.commit();
不知何故,Map似乎包含片段中出现的内容。为什么是这样?我会想到的行为是Id被转移并且Map被跳过。 只需创建一个Activity,一个片段和我的Bar并将其作为Bundle发送即可重复此操作。 我试过寻找答案,但我不太确定如何提出问题。
这是一个应该以这种方式工作的错误或功能吗?
答案 0 :(得分:4)
Parmaling是懒惰地进行的,这意味着当您将Bar
实例传递给Fragment
时,它不会被包围。即writeToParcel
未被调用。
Parceling相当昂贵(就资源而言),所以如果可能的话最好避免它。如果Bundle
未发送到其他进程,则无需将其包裹。通常在涉及IPC时进行分区。因此,即使在配置更改期间,也不需要包裹Bundle
。但是,如果您的进程在活动处于后台时被终止,则参数Bundle
将被分区,因为它存储在另一个进程中。
当您使用Intent
发送时也是如此。
因此,在您的情况下,Map
将在实例被分配时丢失。它只是仍然存在,因为它并没有真正被包围,而且片段收到完全相同的Bar
实例。
答案 1 :(得分:-1)
Bundle不仅有 Parcelable 对象存储实现,还有 Serializable 。如果你看一下HashMap的类,你会看到它实现了Serializable接口:
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable