Java – Parcelable works without proper implementation

Parcelable works without proper implementation… here is a solution to the problem.

Parcelable works without proper implementation

In the Android application, I send bundles from activities to fragments.

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

I used Android Studios Implement Parcelable inteli sense help and automatically generated the above code, but it didn’t implement map.

When I send it to my fragment like this:

 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();

And the Map seems to contain content when it somehow appears in the fragment. Why is that? The behavior I expect is that the ID is transferred and the Map is skipped.
This can be repeated by creating an activity, a fragment, and my bar and sending it as a bundle.
I tried to find answers but wasn’t quite sure how to ask the question.

Is it a bug or a feature that should work this way?

Solution

Parceling is deferred, which means that when you pass a Bar instance to a fragment, it is not packaged. IE。 writeToParcel was not called.

Parceling is very expensive (in terms of resources), so it’s best to avoid it as much as possible. If the bundle is not sent to another process, it does not need to be packaged. Packaging is typically done when IPC is involved. Therefore, there is no need to package bundles even during configuration changes. However, if your process is terminated while the activity is in the background, the parameter bundle is packaged because it is stored in another process.
The same is true when you send it in an intent.

Therefore, in your case, the Map is lost when the instance is actually packaged. It still exists because it’s not really packaged and the fragment receives the exact same bar instance.

Related Problems and Solutions