Parcelable无法正确实施

时间:2017-08-23 06:35:10

标签: java android parcelable

在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发送即可重复此操作。 我试过寻找答案,但我不太确定如何提出问题。

这是一个应该以这种方式工作的错误或功能吗?

2 个答案:

答案 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