如何使用parcelable在活动之间传递对象内的对象
How to pass objects within objects between activities with parcelable
我是 Android Studio 的新手。
我正在尝试使用 parcelable 将 ArrayList 从一个 activity 传递到另一个。在 class 配方中,我声明了另一个 ArrayList,在启动另一个 activity.
时我无法获取它
Recipe.java:
public class Recipe implements Parcelable {
String name;
ArrayList<Ingredient> ingredients;
public Recipe(String name){
this.name = name;
this.ingredients = new ArrayList<>();
}
protected Recipe(Parcel in) {
name = in.readString();
}
public static final Creator<Recipe> CREATOR = new Creator<Recipe>() {
@Override
public Recipe createFromParcel(Parcel in) {
return new Recipe(in);
}
@Override
public Recipe[] newArray(int size) {
return new Recipe[size];
}
};
public void addIngredients(String[] amountList, String[] ingredientList, String[] unitList) {
for (int i = 0; i < ingredientList.length; i++) {
ingredients.add(new Ingredient(ingredientList[i], Double.parseDouble(amountList[i]), unitList[i]));
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
}
}
Ingredient.java:
public class Ingredient implements Parcelable {
private String ingrdnt;
private double amount;
private String unit;
private String cat;
private boolean checkedItem;
public Ingredient(String ingrdnt, double amount, String unit) {
this.ingrdnt = ingrdnt;
this.amount = amount;
this.unit = unit;
//this.cat = category;
this.checkedItem = false;
}
protected Ingredient(Parcel in) {
ingrdnt = in.readString();
amount = in.readDouble();
unit = in.readString();
cat = in.readString();
checkedItem = in.readByte() != 0;
}
public static final Creator<Ingredient> CREATOR = new Creator<Ingredient>() {
@Override
public Ingredient createFromParcel(Parcel in) {
return new Ingredient(in);
}
@Override
public Ingredient[] newArray(int size) {
return new Ingredient[size];
}
};
public double getAmount() {
return amount;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(ingrdnt);
parcel.writeDouble(amount);
parcel.writeString(unit);
parcel.writeString(cat);
parcel.writeByte((byte) (checkedItem ? 1 : 0));
}
}
主要内容:
private ArrayList<Recipe> recipes = new ArrayList<>();
//recipes obviously holds a bunch of recipes so it's not empty.
intent.putExtra("recipes", recipes);
System.out.println(recipes.get(0).ingredients.get(0).getAmount());
System.out: 2.0
秒activity:
recipes = this.getIntent().getParcelableArrayListExtra("recipes");
//Same print as above
System.out.println(recipes.get(0).ingredients.get(0).getAmount());
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
我是不是以错误的方式实现了 parcelable 或者为什么我无法获取 Ingredient 对象?
我读过有关在 Activity 之间传递对象的其他方法,但似乎 parcelable 可能是最好的方法。
是的,您基本上忘记了将 Recipe
的成分写入 Parcel
的输出 Parcel
中,该输出 Parcel
提供给 Recipe.writeToParcel
方法。
你可以把ArrayList<Parcelable>
写成writeTypedList
and read it back with readTypedList
。
所以接受 Parcel
的 Recipe
构造函数应该是这样的:
protected Recipe(Parcel in) {
name = in.readString();
ingredients = new ArrayList<>();
in.readTypedList(ingredients, Ingredient.CREATOR);
}
而 Recipe
的 writeToParcel
应该变成:
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeTypedList(ingredients);
}
您看到的 NullPointerException
是由于您没有在接受 Parcel
的 Recipe
的构造函数中分配一个新的 ArrayList
,所以当您在第二个 Activity
中调用 recipes.get(0).ingredients.get(0).getAmount()
时,ingredients
ArrayList
是 null
,因此 Exception
.
另请注意(但与问题无关)存在一个 writeBoolean
and a readBoolean
,您可以使用它写入和读取 boolean
类型的值(我说的是 Ingredient
class实施)。
尝试一下,让我们知道它是否正常工作。
我是 Android Studio 的新手。
我正在尝试使用 parcelable 将 ArrayList 从一个 activity 传递到另一个。在 class 配方中,我声明了另一个 ArrayList,在启动另一个 activity.
时我无法获取它Recipe.java:
public class Recipe implements Parcelable {
String name;
ArrayList<Ingredient> ingredients;
public Recipe(String name){
this.name = name;
this.ingredients = new ArrayList<>();
}
protected Recipe(Parcel in) {
name = in.readString();
}
public static final Creator<Recipe> CREATOR = new Creator<Recipe>() {
@Override
public Recipe createFromParcel(Parcel in) {
return new Recipe(in);
}
@Override
public Recipe[] newArray(int size) {
return new Recipe[size];
}
};
public void addIngredients(String[] amountList, String[] ingredientList, String[] unitList) {
for (int i = 0; i < ingredientList.length; i++) {
ingredients.add(new Ingredient(ingredientList[i], Double.parseDouble(amountList[i]), unitList[i]));
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
}
}
Ingredient.java:
public class Ingredient implements Parcelable {
private String ingrdnt;
private double amount;
private String unit;
private String cat;
private boolean checkedItem;
public Ingredient(String ingrdnt, double amount, String unit) {
this.ingrdnt = ingrdnt;
this.amount = amount;
this.unit = unit;
//this.cat = category;
this.checkedItem = false;
}
protected Ingredient(Parcel in) {
ingrdnt = in.readString();
amount = in.readDouble();
unit = in.readString();
cat = in.readString();
checkedItem = in.readByte() != 0;
}
public static final Creator<Ingredient> CREATOR = new Creator<Ingredient>() {
@Override
public Ingredient createFromParcel(Parcel in) {
return new Ingredient(in);
}
@Override
public Ingredient[] newArray(int size) {
return new Ingredient[size];
}
};
public double getAmount() {
return amount;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(ingrdnt);
parcel.writeDouble(amount);
parcel.writeString(unit);
parcel.writeString(cat);
parcel.writeByte((byte) (checkedItem ? 1 : 0));
}
}
主要内容:
private ArrayList<Recipe> recipes = new ArrayList<>();
//recipes obviously holds a bunch of recipes so it's not empty.
intent.putExtra("recipes", recipes);
System.out.println(recipes.get(0).ingredients.get(0).getAmount());
System.out: 2.0
秒activity:
recipes = this.getIntent().getParcelableArrayListExtra("recipes");
//Same print as above
System.out.println(recipes.get(0).ingredients.get(0).getAmount());
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
我是不是以错误的方式实现了 parcelable 或者为什么我无法获取 Ingredient 对象?
我读过有关在 Activity 之间传递对象的其他方法,但似乎 parcelable 可能是最好的方法。
是的,您基本上忘记了将 Recipe
的成分写入 Parcel
的输出 Parcel
中,该输出 Parcel
提供给 Recipe.writeToParcel
方法。
你可以把ArrayList<Parcelable>
写成writeTypedList
and read it back with readTypedList
。
所以接受 Parcel
的 Recipe
构造函数应该是这样的:
protected Recipe(Parcel in) {
name = in.readString();
ingredients = new ArrayList<>();
in.readTypedList(ingredients, Ingredient.CREATOR);
}
而 Recipe
的 writeToParcel
应该变成:
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeTypedList(ingredients);
}
您看到的 NullPointerException
是由于您没有在接受 Parcel
的 Recipe
的构造函数中分配一个新的 ArrayList
,所以当您在第二个 Activity
中调用 recipes.get(0).ingredients.get(0).getAmount()
时,ingredients
ArrayList
是 null
,因此 Exception
.
另请注意(但与问题无关)存在一个 writeBoolean
and a readBoolean
,您可以使用它写入和读取 boolean
类型的值(我说的是 Ingredient
class实施)。
尝试一下,让我们知道它是否正常工作。