【问题标题】:How to pass objects within objects between activities with parcelable如何在具有可包裹性的活动之间传递对象内的对象
【发布时间】:2021-01-25 17:44:11
【问题描述】:

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

System.out: 2.0

在第二个活动中:

recipes = this.getIntent().getParcelableArrayListExtra("recipes");
//Same print as above
System.out.println(recipes.get(0).ingredients.get(0).getAmount());

原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“int java.util.ArrayList.size()”

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

我已经了解了在活动之间传递对象的其他方法,但似乎 parcelable 可能是最好的方法。

【问题讨论】:

    标签: java android android-studio parcelable


    【解决方案1】:

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

    您可以用writeTypedListArrayList&lt;Parcelable&gt;,然后用readTypedList 读回。

    所以你的接受ParcelRecipe 构造函数应该是这样的:

    protected Recipe(Parcel in) {
        name = in.readString();
        ingredients = new ArrayList<>();
        in.readTypedList(ingredients, Ingredient.CREATOR);
    }
    

    而你的writeToParcelRecipe 应该变成:

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeTypedList(ingredients);
    }
    

    您看到的NullPointerException 是由于您没有在Recipe 的构造函数中分配一个新的ArrayList,它接受Parcel,所以当您在第二个@ 中调用recipes.get(0).ingredients.get(0).getAmount() 时987654342@ ingredients ArrayListnull,因此是 Exception

    还要注意(但与问题无关)存在一个writeBoolean 和一个readBoolean,您可以使用它们写入和读取boolean 类型的值(我说这是Ingredient 类实现)。

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

    【讨论】:

    • 非常感谢!!它工作得很好:) 你是指 checkItem 变量还是你的意思是我应该从一开始就使用它来实现成分?
    • 没问题。很高兴它有帮助。我指的是checkedItem 确实。
    猜你喜欢
    • 2013-07-13
    • 2013-06-11
    • 2023-03-23
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    相关资源
    最近更新 更多