In fragment, restore an object that contains a list of another object with Parcelable implementation
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have a Car
class implements Parcelable
:
public class Car implements Parcelable {
private long id;
private String model;
public Car(long id, String model) {
this.id = id;
this.model = model;
}
public String getModel() {
return model;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.model);
}
private Car(Parcel in) {
this.id = in.readLong();
this.model = in.readString();
}
public static final Creator<Car> CREATOR = new Creator<Car>() {
@Override
public Car createFromParcel(Parcel source) {
return new Car(source);
}
@Override
public Car newArray(int size) {
return new Car[size];
}
};
}
Then, I have a Store
class which holds a list of cars, it also implements Parcelable
:
public class Store implements Parcelable {
private List<Car> carList = new ArrayList<>();
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> cars) {
carList = cars;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(this.carList);
}
private Store(Parcel in) {
in.readTypedList(carList, Car.CREATOR);
}
public static final Creator<Store> CREATOR = new Creator<Store>() {
@Override
public Store createFromParcel(Parcel source) {
return new Store(source);
}
@Override
public Store newArray(int size) {
return new Store[size];
}
};
}
In a Fragment, I try to restore the Store
instance named myStore
, including the list of cars in it:
class MyFragment extends Fragment {
private Store myStore;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null && savedInstanceState.containsKey(MY_STORE)) {
myStore = savedInstanceState.getParcelable(MY_STORE);
// PROBLEM IS HERE:
// when runtime hit here, the restored myStore contains one car but has id with weird long value and null in model field. WHY?
} else {
// initialize myStore with car list (only one car)
Car myCar = new Car(1, "BMW X1");
List<Car> cars = new ArrayList<>();
cars.add(myCar);
myStore = new Store();
myStore.setCarList(cars);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
if(myStore != null) {
outState.putParcelable(MY_STORE, myStore);
}
super.onSaveInstanceState(outState);
}
}
Problem occur when in MyFragment
, code tries to restore myStore
in onCreate()
. At runtime , the restored myStore
does contain one car in a list, but the car in that list has id with weird long value (e.g. 28429333427126393
) and null
in model
field. WHY? What did I do wrong? How to restore an object contains a list of another object?
android android-fragments parcelable
add a comment |
I have a Car
class implements Parcelable
:
public class Car implements Parcelable {
private long id;
private String model;
public Car(long id, String model) {
this.id = id;
this.model = model;
}
public String getModel() {
return model;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.model);
}
private Car(Parcel in) {
this.id = in.readLong();
this.model = in.readString();
}
public static final Creator<Car> CREATOR = new Creator<Car>() {
@Override
public Car createFromParcel(Parcel source) {
return new Car(source);
}
@Override
public Car newArray(int size) {
return new Car[size];
}
};
}
Then, I have a Store
class which holds a list of cars, it also implements Parcelable
:
public class Store implements Parcelable {
private List<Car> carList = new ArrayList<>();
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> cars) {
carList = cars;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(this.carList);
}
private Store(Parcel in) {
in.readTypedList(carList, Car.CREATOR);
}
public static final Creator<Store> CREATOR = new Creator<Store>() {
@Override
public Store createFromParcel(Parcel source) {
return new Store(source);
}
@Override
public Store newArray(int size) {
return new Store[size];
}
};
}
In a Fragment, I try to restore the Store
instance named myStore
, including the list of cars in it:
class MyFragment extends Fragment {
private Store myStore;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null && savedInstanceState.containsKey(MY_STORE)) {
myStore = savedInstanceState.getParcelable(MY_STORE);
// PROBLEM IS HERE:
// when runtime hit here, the restored myStore contains one car but has id with weird long value and null in model field. WHY?
} else {
// initialize myStore with car list (only one car)
Car myCar = new Car(1, "BMW X1");
List<Car> cars = new ArrayList<>();
cars.add(myCar);
myStore = new Store();
myStore.setCarList(cars);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
if(myStore != null) {
outState.putParcelable(MY_STORE, myStore);
}
super.onSaveInstanceState(outState);
}
}
Problem occur when in MyFragment
, code tries to restore myStore
in onCreate()
. At runtime , the restored myStore
does contain one car in a list, but the car in that list has id with weird long value (e.g. 28429333427126393
) and null
in model
field. WHY? What did I do wrong? How to restore an object contains a list of another object?
android android-fragments parcelable
I don't think your code compiles.myStore = savedInstanceState.getString(MY_STORE)
would fail as you're assigning aString
to a field of typeStore
.
– kcoppock
Jan 3 at 16:35
1
Thanks, that's my typo only, updated togetParcelable(MY_STORE)
– Leem
Jan 3 at 18:16
add a comment |
I have a Car
class implements Parcelable
:
public class Car implements Parcelable {
private long id;
private String model;
public Car(long id, String model) {
this.id = id;
this.model = model;
}
public String getModel() {
return model;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.model);
}
private Car(Parcel in) {
this.id = in.readLong();
this.model = in.readString();
}
public static final Creator<Car> CREATOR = new Creator<Car>() {
@Override
public Car createFromParcel(Parcel source) {
return new Car(source);
}
@Override
public Car newArray(int size) {
return new Car[size];
}
};
}
Then, I have a Store
class which holds a list of cars, it also implements Parcelable
:
public class Store implements Parcelable {
private List<Car> carList = new ArrayList<>();
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> cars) {
carList = cars;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(this.carList);
}
private Store(Parcel in) {
in.readTypedList(carList, Car.CREATOR);
}
public static final Creator<Store> CREATOR = new Creator<Store>() {
@Override
public Store createFromParcel(Parcel source) {
return new Store(source);
}
@Override
public Store newArray(int size) {
return new Store[size];
}
};
}
In a Fragment, I try to restore the Store
instance named myStore
, including the list of cars in it:
class MyFragment extends Fragment {
private Store myStore;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null && savedInstanceState.containsKey(MY_STORE)) {
myStore = savedInstanceState.getParcelable(MY_STORE);
// PROBLEM IS HERE:
// when runtime hit here, the restored myStore contains one car but has id with weird long value and null in model field. WHY?
} else {
// initialize myStore with car list (only one car)
Car myCar = new Car(1, "BMW X1");
List<Car> cars = new ArrayList<>();
cars.add(myCar);
myStore = new Store();
myStore.setCarList(cars);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
if(myStore != null) {
outState.putParcelable(MY_STORE, myStore);
}
super.onSaveInstanceState(outState);
}
}
Problem occur when in MyFragment
, code tries to restore myStore
in onCreate()
. At runtime , the restored myStore
does contain one car in a list, but the car in that list has id with weird long value (e.g. 28429333427126393
) and null
in model
field. WHY? What did I do wrong? How to restore an object contains a list of another object?
android android-fragments parcelable
I have a Car
class implements Parcelable
:
public class Car implements Parcelable {
private long id;
private String model;
public Car(long id, String model) {
this.id = id;
this.model = model;
}
public String getModel() {
return model;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.model);
}
private Car(Parcel in) {
this.id = in.readLong();
this.model = in.readString();
}
public static final Creator<Car> CREATOR = new Creator<Car>() {
@Override
public Car createFromParcel(Parcel source) {
return new Car(source);
}
@Override
public Car newArray(int size) {
return new Car[size];
}
};
}
Then, I have a Store
class which holds a list of cars, it also implements Parcelable
:
public class Store implements Parcelable {
private List<Car> carList = new ArrayList<>();
public List<Car> getCarList() {
return carList;
}
public void setCarList(List<Car> cars) {
carList = cars;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(this.carList);
}
private Store(Parcel in) {
in.readTypedList(carList, Car.CREATOR);
}
public static final Creator<Store> CREATOR = new Creator<Store>() {
@Override
public Store createFromParcel(Parcel source) {
return new Store(source);
}
@Override
public Store newArray(int size) {
return new Store[size];
}
};
}
In a Fragment, I try to restore the Store
instance named myStore
, including the list of cars in it:
class MyFragment extends Fragment {
private Store myStore;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null && savedInstanceState.containsKey(MY_STORE)) {
myStore = savedInstanceState.getParcelable(MY_STORE);
// PROBLEM IS HERE:
// when runtime hit here, the restored myStore contains one car but has id with weird long value and null in model field. WHY?
} else {
// initialize myStore with car list (only one car)
Car myCar = new Car(1, "BMW X1");
List<Car> cars = new ArrayList<>();
cars.add(myCar);
myStore = new Store();
myStore.setCarList(cars);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
if(myStore != null) {
outState.putParcelable(MY_STORE, myStore);
}
super.onSaveInstanceState(outState);
}
}
Problem occur when in MyFragment
, code tries to restore myStore
in onCreate()
. At runtime , the restored myStore
does contain one car in a list, but the car in that list has id with weird long value (e.g. 28429333427126393
) and null
in model
field. WHY? What did I do wrong? How to restore an object contains a list of another object?
android android-fragments parcelable
android android-fragments parcelable
edited Jan 3 at 18:15
Leem
asked Jan 3 at 16:15
LeemLeem
5,0152469103
5,0152469103
I don't think your code compiles.myStore = savedInstanceState.getString(MY_STORE)
would fail as you're assigning aString
to a field of typeStore
.
– kcoppock
Jan 3 at 16:35
1
Thanks, that's my typo only, updated togetParcelable(MY_STORE)
– Leem
Jan 3 at 18:16
add a comment |
I don't think your code compiles.myStore = savedInstanceState.getString(MY_STORE)
would fail as you're assigning aString
to a field of typeStore
.
– kcoppock
Jan 3 at 16:35
1
Thanks, that's my typo only, updated togetParcelable(MY_STORE)
– Leem
Jan 3 at 18:16
I don't think your code compiles.
myStore = savedInstanceState.getString(MY_STORE)
would fail as you're assigning a String
to a field of type Store
.– kcoppock
Jan 3 at 16:35
I don't think your code compiles.
myStore = savedInstanceState.getString(MY_STORE)
would fail as you're assigning a String
to a field of type Store
.– kcoppock
Jan 3 at 16:35
1
1
Thanks, that's my typo only, updated to
getParcelable(MY_STORE)
– Leem
Jan 3 at 18:16
Thanks, that's my typo only, updated to
getParcelable(MY_STORE)
– Leem
Jan 3 at 18:16
add a comment |
1 Answer
1
active
oldest
votes
This problem usually occurs when your carList
instance was null so you wrote a null object in parcelable and try to read from it.
One of the options is that you initialize your list when it's null and then write it in parcelable. Using this case your list will always have a reference after restoration which might not be what you're looking for.
The other approach is to write a byte value before writing your list into parcelable indicating that your list was null or you should expect some value from it. For this case I'm using this helper class which solved my own problem. Based on my needs, I have made some improvements. Here is my version if you'd prefer to use it:
public class ParcelableUtils {
public static void write(Parcel dest, String string) {
dest.writeByte((byte) (string == null ? 0 : 1));
if (string != null) {
dest.writeString(string);
}
}
public static String readString(Parcel source) {
if (source.readByte() == 1) {
return source.readString();
}
return null;
}
public static void write(Parcel dest, Parcelable parcelable, int flags) {
dest.writeByte((byte) (parcelable == null ? 0 : 1));
if (parcelable != null) {
dest.writeParcelable(parcelable, flags);
}
}
public static <T extends Parcelable> T readParcelable(Parcel source) {
if (source.readByte() == 1) {
return source.readParcelable(null);
}
return null;
}
public static <T extends Parcelable> T readParcelable(Parcel source, Class objectClass) {
if (source.readByte() == 1) {
return source.readParcelable(objectClass.getClassLoader());
}
return null;
}
public static void write(Parcel dest, Map<String, String> strings) {
if (strings == null) {
dest.writeInt(-1);
}
{
dest.writeInt(strings.keySet().size());
for (String key : strings.keySet()) {
dest.writeString(key);
dest.writeString(strings.get(key));
}
}
}
public static Map<String, String> readStringMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
String value = source.readString();
map.put(key, value);
}
return map;
}
public static <T extends Parcelable> void write(Parcel dest, Map<String, T> objects, int flags) {
if (objects == null) {
dest.writeInt(-1);
} else {
dest.writeInt(objects.keySet().size());
for (String key : objects.keySet()) {
dest.writeString(key);
dest.writeParcelable(objects.get(key), flags);
}
}
}
public static <T extends Parcelable> Map<String, T> readParcelableMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, T> map = new HashMap<String, T>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
T value = source.readParcelable(null);
map.put(key, value);
}
return map;
}
public static void write(Parcel dest, URL url) {
dest.writeString(url.toExternalForm());
}
public static URL readURL(Parcel source) {
try {
return new URL(source.readString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static void write(Parcel dest, Date date) {
dest.writeByte((byte) (date == null ? 0 : 1));
if (date != null) {
dest.writeLong(date.getTime());
}
}
public static Date readDate(Parcel source) {
if (source.readByte() == 1) {
return new Date(source.readLong());
}
return null;
}
public static <T extends java.lang.Enum<T>> void write(Parcel dest, java.lang.Enum<T> enu) {
if (enu == null) {
dest.writeString("");
} else {
dest.writeString(enu.name());
}
}
public static <T extends java.lang.Enum<T>> T readEnum(Parcel dest, Class<T> clazz) {
String name = dest.readString();
if ("".equals(name)) {
return null;
}
return java.lang.Enum.valueOf(clazz, name);
}
public static void write(Parcel dest, boolean bool) {
dest.writeByte((byte) (bool ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
public static <T extends Parcelable> void write(Parcel dest,
List<T> fields, int flags) {
if (fields == null) {
dest.writeInt(-1);
} else {
dest.writeInt(fields.size());
for (T field : fields) {
dest.writeParcelable(field, flags);
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> List<T> readParcelableList(
Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
}
ArrayList<T> list = new ArrayList<T>();
for (int i = 0; i < size; i++) {
list.add((T) source.readParcelable(null));
}
return list;
}
}
Hope it helps.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54026032%2fin-fragment-restore-an-object-that-contains-a-list-of-another-object-with-parce%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This problem usually occurs when your carList
instance was null so you wrote a null object in parcelable and try to read from it.
One of the options is that you initialize your list when it's null and then write it in parcelable. Using this case your list will always have a reference after restoration which might not be what you're looking for.
The other approach is to write a byte value before writing your list into parcelable indicating that your list was null or you should expect some value from it. For this case I'm using this helper class which solved my own problem. Based on my needs, I have made some improvements. Here is my version if you'd prefer to use it:
public class ParcelableUtils {
public static void write(Parcel dest, String string) {
dest.writeByte((byte) (string == null ? 0 : 1));
if (string != null) {
dest.writeString(string);
}
}
public static String readString(Parcel source) {
if (source.readByte() == 1) {
return source.readString();
}
return null;
}
public static void write(Parcel dest, Parcelable parcelable, int flags) {
dest.writeByte((byte) (parcelable == null ? 0 : 1));
if (parcelable != null) {
dest.writeParcelable(parcelable, flags);
}
}
public static <T extends Parcelable> T readParcelable(Parcel source) {
if (source.readByte() == 1) {
return source.readParcelable(null);
}
return null;
}
public static <T extends Parcelable> T readParcelable(Parcel source, Class objectClass) {
if (source.readByte() == 1) {
return source.readParcelable(objectClass.getClassLoader());
}
return null;
}
public static void write(Parcel dest, Map<String, String> strings) {
if (strings == null) {
dest.writeInt(-1);
}
{
dest.writeInt(strings.keySet().size());
for (String key : strings.keySet()) {
dest.writeString(key);
dest.writeString(strings.get(key));
}
}
}
public static Map<String, String> readStringMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
String value = source.readString();
map.put(key, value);
}
return map;
}
public static <T extends Parcelable> void write(Parcel dest, Map<String, T> objects, int flags) {
if (objects == null) {
dest.writeInt(-1);
} else {
dest.writeInt(objects.keySet().size());
for (String key : objects.keySet()) {
dest.writeString(key);
dest.writeParcelable(objects.get(key), flags);
}
}
}
public static <T extends Parcelable> Map<String, T> readParcelableMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, T> map = new HashMap<String, T>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
T value = source.readParcelable(null);
map.put(key, value);
}
return map;
}
public static void write(Parcel dest, URL url) {
dest.writeString(url.toExternalForm());
}
public static URL readURL(Parcel source) {
try {
return new URL(source.readString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static void write(Parcel dest, Date date) {
dest.writeByte((byte) (date == null ? 0 : 1));
if (date != null) {
dest.writeLong(date.getTime());
}
}
public static Date readDate(Parcel source) {
if (source.readByte() == 1) {
return new Date(source.readLong());
}
return null;
}
public static <T extends java.lang.Enum<T>> void write(Parcel dest, java.lang.Enum<T> enu) {
if (enu == null) {
dest.writeString("");
} else {
dest.writeString(enu.name());
}
}
public static <T extends java.lang.Enum<T>> T readEnum(Parcel dest, Class<T> clazz) {
String name = dest.readString();
if ("".equals(name)) {
return null;
}
return java.lang.Enum.valueOf(clazz, name);
}
public static void write(Parcel dest, boolean bool) {
dest.writeByte((byte) (bool ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
public static <T extends Parcelable> void write(Parcel dest,
List<T> fields, int flags) {
if (fields == null) {
dest.writeInt(-1);
} else {
dest.writeInt(fields.size());
for (T field : fields) {
dest.writeParcelable(field, flags);
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> List<T> readParcelableList(
Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
}
ArrayList<T> list = new ArrayList<T>();
for (int i = 0; i < size; i++) {
list.add((T) source.readParcelable(null));
}
return list;
}
}
Hope it helps.
add a comment |
This problem usually occurs when your carList
instance was null so you wrote a null object in parcelable and try to read from it.
One of the options is that you initialize your list when it's null and then write it in parcelable. Using this case your list will always have a reference after restoration which might not be what you're looking for.
The other approach is to write a byte value before writing your list into parcelable indicating that your list was null or you should expect some value from it. For this case I'm using this helper class which solved my own problem. Based on my needs, I have made some improvements. Here is my version if you'd prefer to use it:
public class ParcelableUtils {
public static void write(Parcel dest, String string) {
dest.writeByte((byte) (string == null ? 0 : 1));
if (string != null) {
dest.writeString(string);
}
}
public static String readString(Parcel source) {
if (source.readByte() == 1) {
return source.readString();
}
return null;
}
public static void write(Parcel dest, Parcelable parcelable, int flags) {
dest.writeByte((byte) (parcelable == null ? 0 : 1));
if (parcelable != null) {
dest.writeParcelable(parcelable, flags);
}
}
public static <T extends Parcelable> T readParcelable(Parcel source) {
if (source.readByte() == 1) {
return source.readParcelable(null);
}
return null;
}
public static <T extends Parcelable> T readParcelable(Parcel source, Class objectClass) {
if (source.readByte() == 1) {
return source.readParcelable(objectClass.getClassLoader());
}
return null;
}
public static void write(Parcel dest, Map<String, String> strings) {
if (strings == null) {
dest.writeInt(-1);
}
{
dest.writeInt(strings.keySet().size());
for (String key : strings.keySet()) {
dest.writeString(key);
dest.writeString(strings.get(key));
}
}
}
public static Map<String, String> readStringMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
String value = source.readString();
map.put(key, value);
}
return map;
}
public static <T extends Parcelable> void write(Parcel dest, Map<String, T> objects, int flags) {
if (objects == null) {
dest.writeInt(-1);
} else {
dest.writeInt(objects.keySet().size());
for (String key : objects.keySet()) {
dest.writeString(key);
dest.writeParcelable(objects.get(key), flags);
}
}
}
public static <T extends Parcelable> Map<String, T> readParcelableMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, T> map = new HashMap<String, T>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
T value = source.readParcelable(null);
map.put(key, value);
}
return map;
}
public static void write(Parcel dest, URL url) {
dest.writeString(url.toExternalForm());
}
public static URL readURL(Parcel source) {
try {
return new URL(source.readString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static void write(Parcel dest, Date date) {
dest.writeByte((byte) (date == null ? 0 : 1));
if (date != null) {
dest.writeLong(date.getTime());
}
}
public static Date readDate(Parcel source) {
if (source.readByte() == 1) {
return new Date(source.readLong());
}
return null;
}
public static <T extends java.lang.Enum<T>> void write(Parcel dest, java.lang.Enum<T> enu) {
if (enu == null) {
dest.writeString("");
} else {
dest.writeString(enu.name());
}
}
public static <T extends java.lang.Enum<T>> T readEnum(Parcel dest, Class<T> clazz) {
String name = dest.readString();
if ("".equals(name)) {
return null;
}
return java.lang.Enum.valueOf(clazz, name);
}
public static void write(Parcel dest, boolean bool) {
dest.writeByte((byte) (bool ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
public static <T extends Parcelable> void write(Parcel dest,
List<T> fields, int flags) {
if (fields == null) {
dest.writeInt(-1);
} else {
dest.writeInt(fields.size());
for (T field : fields) {
dest.writeParcelable(field, flags);
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> List<T> readParcelableList(
Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
}
ArrayList<T> list = new ArrayList<T>();
for (int i = 0; i < size; i++) {
list.add((T) source.readParcelable(null));
}
return list;
}
}
Hope it helps.
add a comment |
This problem usually occurs when your carList
instance was null so you wrote a null object in parcelable and try to read from it.
One of the options is that you initialize your list when it's null and then write it in parcelable. Using this case your list will always have a reference after restoration which might not be what you're looking for.
The other approach is to write a byte value before writing your list into parcelable indicating that your list was null or you should expect some value from it. For this case I'm using this helper class which solved my own problem. Based on my needs, I have made some improvements. Here is my version if you'd prefer to use it:
public class ParcelableUtils {
public static void write(Parcel dest, String string) {
dest.writeByte((byte) (string == null ? 0 : 1));
if (string != null) {
dest.writeString(string);
}
}
public static String readString(Parcel source) {
if (source.readByte() == 1) {
return source.readString();
}
return null;
}
public static void write(Parcel dest, Parcelable parcelable, int flags) {
dest.writeByte((byte) (parcelable == null ? 0 : 1));
if (parcelable != null) {
dest.writeParcelable(parcelable, flags);
}
}
public static <T extends Parcelable> T readParcelable(Parcel source) {
if (source.readByte() == 1) {
return source.readParcelable(null);
}
return null;
}
public static <T extends Parcelable> T readParcelable(Parcel source, Class objectClass) {
if (source.readByte() == 1) {
return source.readParcelable(objectClass.getClassLoader());
}
return null;
}
public static void write(Parcel dest, Map<String, String> strings) {
if (strings == null) {
dest.writeInt(-1);
}
{
dest.writeInt(strings.keySet().size());
for (String key : strings.keySet()) {
dest.writeString(key);
dest.writeString(strings.get(key));
}
}
}
public static Map<String, String> readStringMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
String value = source.readString();
map.put(key, value);
}
return map;
}
public static <T extends Parcelable> void write(Parcel dest, Map<String, T> objects, int flags) {
if (objects == null) {
dest.writeInt(-1);
} else {
dest.writeInt(objects.keySet().size());
for (String key : objects.keySet()) {
dest.writeString(key);
dest.writeParcelable(objects.get(key), flags);
}
}
}
public static <T extends Parcelable> Map<String, T> readParcelableMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, T> map = new HashMap<String, T>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
T value = source.readParcelable(null);
map.put(key, value);
}
return map;
}
public static void write(Parcel dest, URL url) {
dest.writeString(url.toExternalForm());
}
public static URL readURL(Parcel source) {
try {
return new URL(source.readString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static void write(Parcel dest, Date date) {
dest.writeByte((byte) (date == null ? 0 : 1));
if (date != null) {
dest.writeLong(date.getTime());
}
}
public static Date readDate(Parcel source) {
if (source.readByte() == 1) {
return new Date(source.readLong());
}
return null;
}
public static <T extends java.lang.Enum<T>> void write(Parcel dest, java.lang.Enum<T> enu) {
if (enu == null) {
dest.writeString("");
} else {
dest.writeString(enu.name());
}
}
public static <T extends java.lang.Enum<T>> T readEnum(Parcel dest, Class<T> clazz) {
String name = dest.readString();
if ("".equals(name)) {
return null;
}
return java.lang.Enum.valueOf(clazz, name);
}
public static void write(Parcel dest, boolean bool) {
dest.writeByte((byte) (bool ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
public static <T extends Parcelable> void write(Parcel dest,
List<T> fields, int flags) {
if (fields == null) {
dest.writeInt(-1);
} else {
dest.writeInt(fields.size());
for (T field : fields) {
dest.writeParcelable(field, flags);
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> List<T> readParcelableList(
Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
}
ArrayList<T> list = new ArrayList<T>();
for (int i = 0; i < size; i++) {
list.add((T) source.readParcelable(null));
}
return list;
}
}
Hope it helps.
This problem usually occurs when your carList
instance was null so you wrote a null object in parcelable and try to read from it.
One of the options is that you initialize your list when it's null and then write it in parcelable. Using this case your list will always have a reference after restoration which might not be what you're looking for.
The other approach is to write a byte value before writing your list into parcelable indicating that your list was null or you should expect some value from it. For this case I'm using this helper class which solved my own problem. Based on my needs, I have made some improvements. Here is my version if you'd prefer to use it:
public class ParcelableUtils {
public static void write(Parcel dest, String string) {
dest.writeByte((byte) (string == null ? 0 : 1));
if (string != null) {
dest.writeString(string);
}
}
public static String readString(Parcel source) {
if (source.readByte() == 1) {
return source.readString();
}
return null;
}
public static void write(Parcel dest, Parcelable parcelable, int flags) {
dest.writeByte((byte) (parcelable == null ? 0 : 1));
if (parcelable != null) {
dest.writeParcelable(parcelable, flags);
}
}
public static <T extends Parcelable> T readParcelable(Parcel source) {
if (source.readByte() == 1) {
return source.readParcelable(null);
}
return null;
}
public static <T extends Parcelable> T readParcelable(Parcel source, Class objectClass) {
if (source.readByte() == 1) {
return source.readParcelable(objectClass.getClassLoader());
}
return null;
}
public static void write(Parcel dest, Map<String, String> strings) {
if (strings == null) {
dest.writeInt(-1);
}
{
dest.writeInt(strings.keySet().size());
for (String key : strings.keySet()) {
dest.writeString(key);
dest.writeString(strings.get(key));
}
}
}
public static Map<String, String> readStringMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
String value = source.readString();
map.put(key, value);
}
return map;
}
public static <T extends Parcelable> void write(Parcel dest, Map<String, T> objects, int flags) {
if (objects == null) {
dest.writeInt(-1);
} else {
dest.writeInt(objects.keySet().size());
for (String key : objects.keySet()) {
dest.writeString(key);
dest.writeParcelable(objects.get(key), flags);
}
}
}
public static <T extends Parcelable> Map<String, T> readParcelableMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, T> map = new HashMap<String, T>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
T value = source.readParcelable(null);
map.put(key, value);
}
return map;
}
public static void write(Parcel dest, URL url) {
dest.writeString(url.toExternalForm());
}
public static URL readURL(Parcel source) {
try {
return new URL(source.readString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static void write(Parcel dest, Date date) {
dest.writeByte((byte) (date == null ? 0 : 1));
if (date != null) {
dest.writeLong(date.getTime());
}
}
public static Date readDate(Parcel source) {
if (source.readByte() == 1) {
return new Date(source.readLong());
}
return null;
}
public static <T extends java.lang.Enum<T>> void write(Parcel dest, java.lang.Enum<T> enu) {
if (enu == null) {
dest.writeString("");
} else {
dest.writeString(enu.name());
}
}
public static <T extends java.lang.Enum<T>> T readEnum(Parcel dest, Class<T> clazz) {
String name = dest.readString();
if ("".equals(name)) {
return null;
}
return java.lang.Enum.valueOf(clazz, name);
}
public static void write(Parcel dest, boolean bool) {
dest.writeByte((byte) (bool ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
public static <T extends Parcelable> void write(Parcel dest,
List<T> fields, int flags) {
if (fields == null) {
dest.writeInt(-1);
} else {
dest.writeInt(fields.size());
for (T field : fields) {
dest.writeParcelable(field, flags);
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> List<T> readParcelableList(
Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
}
ArrayList<T> list = new ArrayList<T>();
for (int i = 0; i < size; i++) {
list.add((T) source.readParcelable(null));
}
return list;
}
}
Hope it helps.
answered Jan 3 at 16:34
SdghasemiSdghasemi
1,5261322
1,5261322
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54026032%2fin-fragment-restore-an-object-that-contains-a-list-of-another-object-with-parce%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I don't think your code compiles.
myStore = savedInstanceState.getString(MY_STORE)
would fail as you're assigning aString
to a field of typeStore
.– kcoppock
Jan 3 at 16:35
1
Thanks, that's my typo only, updated to
getParcelable(MY_STORE)
– Leem
Jan 3 at 18:16