Parcelable 在没有正确实施的情况下工作

Parcelable works without correct implementation

在 Android 应用程序中,我将一个包从 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 Studios Implement Parcelable inteli sense 帮助并自动生成了上述代码,但它没有实现地图。

当我像这样将它发送到我的片段时:

 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 发送来重复。 我尝试寻找答案,但不太确定如何提出问题。

这是错误还是应该以这种方式工作的功能?

Bundle不仅有Parcelable对象存储实现,还有Serializable。如果你看一下 HashMap 的 class 你会看到它实现了 Serializable 接口:

public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

打包是延迟完成的,这意味着当您将 Bar 实例传递给 Fragment 时,它不会被打包。 IE。 writeToParcel 未调用。

Parceling 非常昂贵(就资源而言),因此最好尽可能避免。如果 Bundle 没有发送到另一个进程,则不需要打包它。通常在涉及 IPC 时进行打包。因此,即使在配置更改期间,也无需打包 Bundle。但是,如果当 activity 在后台时您的进程被终止,则参数 Bundle 将被打包,因为它存储在另一个进程中。 在 Intent.

中发送时也是如此

因此,在您的情况下,Map 会在实际打包实例时丢失。它仍然存在是因为它并没有真正被打包并且 Fragment 接收到 Bar.

的完全相同的实例