如何使用parcelable在活动之间传递对象内的对象

问题描述

我是 Android Studio 的新手。

我正在尝试使用 Parcelable 将 ArrayList 从一个活动传递到另一个活动。在 Recipe 类中,我声明了另一个 ArrayList,在启动其他活动时我无法获取它。

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

系统输出:2.0

在第二个活动中:

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 the virtual method 'int java.util.ArrayList.size()' on an null object reference

我是否以错误的方式实现了 Parcelable 或者为什么我无法获得 Ingredient 对象?

我已经阅读了有关在活动之间传递对象的其他方法,但似乎 Parcelable 可能是最好的方法

解决方法

是的,您基本上忘记将 Recipe 的成分写入输出 Parcel 中,该输出 Recipe.writeToParcel 提供给 ArrayList<Parcelable> 方法。

您可以使用 writeTypedList 写入 Recipe,然后使用 readTypedList 读取它。

所以你接受 Parcelprotected Recipe(Parcel in) { name = in.readString(); ingredients = new ArrayList<>(); in.readTypedList(ingredients,Ingredient.CREATOR); } 构造函数应该是这样的:

writeToParcel

而您的 Recipe@Override public void writeToParcel(Parcel parcel,int i) { parcel.writeString(name); parcel.writeTypedList(ingredients); } 应该变成:

NullPointerException

您看到的 ArrayList 是因为您没有在接受 RecipeParcel 的构造函数中分配新的 recipes.get(0).ingredients.get(0).getAmount(),所以当您在第二个 Activity 中调用 ingredientsArrayList nullException,因此 boolean

另请注意(但与问题无关)存在一个 writeBoolean 和一个 readBoolean,您可以使用它们来写入和读取 Ingredient 类型的值(我说这个是为了box-sizing: border-box 类实现)。

尝试一下,让我们知道它是否工作正常。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...