In a Android App I'm sending a Bundle from an Activity to a Fragment.
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've used Android Studios Implement Parcelable inteli sense help and auto generated the above code and it has no implementation for the Map.
When I send this 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 somehow the Map appears to contain the content when it appears in the fragment. Why is this? The behaviour I would excpect is that Id is transfered and Map is skipped. This is possible to repeat by just creating an Activity, a fragment and my Bar and send it as a Bundle. I've tried searching for an answer but I'm not quite sure on how to formulate the question.
Is it a bug or a feature that is supposed to work this way?
Parceling is done lazily, which means your Bar
instance is not being parceled when you pass it to the Fragment
. I.e. writeToParcel
is not called.
Parceling is quite expensive (in terms of resources), so it's better to avoid it if possible. If the Bundle
is not sent to another process there is no need to parcel it. Usually parceling is done when IPC is involved. So even during a configuration change there is no need to parcel the Bundle
. If, however, your process is killed when the activity is in the background, the arguments Bundle
would be parceled because it's stored in another process.
This is also true when you send it in an Intent
.
So in your case the Map
would go lost when the instance is actually parceled. It's only still present because it's not really parceled and the Fragment receives the exact same instance of Bar
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With